21 Commits
Author SHA1 Message Date
Niko WuandClaude Code 1d38af3fe3 fix(core): derive workspace session store from the engine store path (#1926)
getOrCreateWorkspaceAgent built the per-workspace session file as
filepath.Join(filepath.Dir(e.sessions.StorePath()), ...). With no store
path configured — which is how every engine in the test suite is built —
filepath.Dir("") is ".", so the path collapsed to a bare relative
"<engine>_ws_<hash>.json" and the session manager wrote it into the
process working directory. That is what littered core/ with test_ws_*.json
during `go test ./core/`.

An empty store path already means "no persistence" everywhere else in the
session manager (saveLocked returns early), so it now means the same here:
the workspace manager is built unpersisted instead of inventing a path.
A configured store path still derives the workspace file beside it, as
before.

Regressions: an engine without a store path yields a workspace manager
whose StorePath() is empty, and a configured one still derives
test_ws_<hash>.json in the store's directory.

Also ignores the stale files contributors already have on disk.

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-09-29 10:40:53 +08:00
cg33andqa-cursor fec094f9f0 chore(gitignore): add .worktrees/ — local-only multi-agent scratch dirs (#1443)
Multiple AI agents (qa-*, dev-*, release-*) routinely create ad-hoc git
worktrees under .worktrees/<task-name> for parallel branch work (PR
review, hotfix prep, release cherry-pick, etc.). These directories are
local-only by convention and must not be staged or committed.

Without this rule, `git add .` or `git add -A` from the repo root can
accidentally stage tens of worktrees (897 MB locally as of writing).

Establishes .worktrees/ as the canonical location for such scratch
checkouts, documented inline so future contributors / agents see the
intent.

Co-authored-by: qa-cursor <qa-cursor@cc-connect.local>
2026-06-28 20:21:06 +08:00
ClaudeandCursor 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
ClaudeandCursor fa993f9eae chore: ignore web/tsconfig.tsbuildinfo (TS incremental build cache)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 10:14:46 +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
Aleksey BondarenkoandClaude Opus 4.7 cb2fb67875 feat(platform/max): webhook delivery mode + deployment docs (#818)
* feat(platform/max): webhook mode, typing presence, long-poll tuning

Adds webhook delivery as an alternative to long-polling (required by
MAX from 2026-05-11, when long-poll is throttled to 2 RPS):

- New `webhook_url` / `webhook_listen` config options. When `webhook_url`
  is set, the platform registers a subscription with MAX, runs an HTTP
  listener on `webhook_listen`, and skips the long-poll loop. Stop()
  best-effort unsubscribes so MAX stops delivering to a dead URL.
- Webhook handler ack's MAX with a fast 200 and processes updates
  asynchronously so agent latency never back-pressures delivery.

Adds typing/read presence indicators:

- `StartTyping` drives MAX's `typing_on` action on a 4s ticker.
- Incoming messages get fire-and-forget `mark_seen` so the user sees
  the read tick.

Tightens long-poll timeouts to prevent retry storms:

- `pollTimeout` 20 → 30 (matches MAX dev docs default)
- `httpTimeout` 35s → 90s (must exceed pollTimeout with margin so
  transient backend lag doesn't trip client cancellation).

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

* feat(platform/max): add webhook_path and webhook_secret options + deployment docs

New config options for hardening webhook deployments:

- `webhook_path` (default "/webhook") — lets multiple bots share one
  domain (e.g. /bot1, /bot2). Leading slash is normalized.
- `webhook_secret` — optional shared secret. If set, incoming requests
  must carry it in the `X-Webhook-Secret` header or `?s=` query param;
  mismatches return 401. Compared with `subtle.ConstantTimeCompare` to
  resist timing attacks. Recommended pattern: set the secret as an
  nginx `proxy_set_header` so it never appears in URLs or upstream logs.

Adds `docs/max-webhook.md` with three deployment topologies (VPS +
reverse proxy, home + VPS SSH-tunnel, long-poll), copy-paste nginx /
Caddy / systemd samples, a config field reference, mode-switching
notes, and troubleshooting. Updates `config.example.toml` to point
users at the doc and show the new fields.

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

* chore: ignore manual cc-connect.bak backups and runtime *.toml.lock files

The bot acquires a *.toml.lock at startup to prevent multiple instances
fighting over the same config. These are runtime artifacts, not source.

cc-connect.bak-* is the manual backup naming convention used during
local development (cc-connect.bak-deadlock-fix-..., cc-connect.bak-pre-
webhook-..., etc.). Each is a 30 MB binary; keeping them out of
`git status` makes the working tree readable again.

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

* fix(platform/max): correct webhook secret header + periodic resubscribe

The handler was checking X-Webhook-Secret, but MAX sends the configured
secret as X-Max-Bot-Api-Secret per dev.max.ru/docs-api — which meant the
existing webhook_secret option silently rejected every legitimate webhook
with 401. Also propagate the secret in POST /subscriptions so MAX actually
includes the header.

Add a periodic re-subscribe loop (default 5m, configurable via
webhook_resubscribe_interval) to work around server-side subscription
drops observed on 2026-05-04 (three drops in ~1.5h on a single run, all
POST /webhook responses 200). MAX overwrites in place, so re-subscribing
is idempotent.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:19:58 +08:00
Aleksey BondarenkoandClaude Opus 4.7 b187acd147 feat(platform/max): add MAX messenger bridge with bidirectional file and voice support (#742)
* feat(platform/max): add MAX messenger bridge with bidirectional file and voice support

- Implement core.Platform plus InlineButtonSender, ImageSender, FileSender,
  AudioSender, MessageUpdater, FormattingInstructionProvider,
  ReplyContextReconstructor
- Two-step attachment upload via POST /uploads + multipart to CDN
- Route incoming audio (type=audio and audio/* file mime) to
  core.Message.Audio so the speech pipeline transcribes it for the agent
- Outgoing voice replies via SendAudio for the TTS pipeline
- Retry on attachment.not.ready with exponential backoff
- Long poll /updates with reconnect backoff and allow_from filtering
- Register max in Makefile ALL_PLATFORMS and document in config.example.toml
- Tighten .gitignore: ignore config.*.toml (except example) and *.old
- 19 unit/integration tests with httptest mock, passes -race

Refs #741

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

* fix(platform/max): handle real MAX CDN response shapes and audio download

Issues discovered when testing end-to-end with the live MAX API:

1. Image CDN returns nested {"photos": {<id>: {"token": ...}}}, not a flat
   {"token": ...}. Parse the right shape per kind.

2. Audio CDN returns XML "<retval>1</retval>" rather than JSON. The real
   attachment token is delivered in the /uploads response itself for
   video/audio, so we use urlInfo.Token as the source of truth and only
   scan the CDN body opportunistically.

3. /audios/{token} endpoint does not exist in MAX (returns 404). Incoming
   voice payloads already carry the download URL directly, mirroring
   images/files. Use payload.url; fall back to resolveMediaURL only if
   empty (for video where token resolution may still apply).

Also raise the speech HTTP client timeout from 60s to 5m — enough for the
first-request cold-start case when a local Whisper backend has to download
or JIT-load the model before responding.

Tests updated to emit the real CDN response shapes per attachment type.

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

* refactor(platform/max): address review — dedup + idiomatic session key parse

- Add core.MessageDedup to Platform and check msg.Body.Mid / callback ID
  in handleMessage and handleCallback. Guards against reprocessing on
  poll-loop reconnect edge cases, matching the pattern used by feishu/
  dingtalk/wecom platforms.
- Replace fmt.Sscanf in ReconstructReplyCtx with strings.CutPrefix +
  strings.Cut — more idiomatic Go, simpler to read, and handles the
  "max:" prefix and optional ":userID" suffix without a manual loop.
- Add TestHandleMessageDedupsByID regression test.

Addresses review feedback on #742.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:36:57 +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
q107580018 b8d75f73af fix(feishu): improve delete and /model card refresh flows (#645) 2026-04-16 14:43:53 +08: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
yzlu0917 68dcb10906 fix: avoid web embed build failures (#391) 2026-04-02 09:28:38 +08:00
cg33andClaude Opus 4.6 2e9d75c231 fix(opencode): add warn logs when sqlite3 CLI is missing (#319)
* feat(web): add web admin dashboard (React + Tailwind + TypeScript)

Full-featured management UI for CC-Connect instances:
- Token-based auth, dark/light/system theme, i18n (EN/ZH/ZH-TW/JA/ES)
- Dashboard with system status, project overview
- Project management with providers, heartbeat, settings tabs
- Session list and chat interface with Markdown rendering
- Cron job management (create/delete)
- Bridge adapter viewer
- System config viewer, logs, restart/reload controls
- All endpoints aligned with docs/management-api.md

Made-with: Cursor

* feat(web): improve session UI, markdown rendering, and API richness

- Enrich session list/detail API with live status, last_message preview,
  agent_type, platform, user metadata, and timestamps
- Add SessionKeyMap() helper to core/session.go for ID-to-key mapping
- Redesign SessionList as responsive grid layout with project filtering,
  time-ago display, and last message preview
- Upgrade markdown rendering: rehype-highlight for syntax highlighting,
  @tailwindcss/typography for proper prose styling, copy-to-clipboard on
  code blocks, GitHub light/dark themes
- Show live/offline session status; disable message input for non-live sessions
- Update management-api.md to document new session fields
- Remove node_modules from git tracking and add to .gitignore

Made-with: Cursor

* chore: add .vite/ to .gitignore

Made-with: Cursor

* fix(opencode): add warn logs when sqlite3 CLI is missing or query fails

The /list command silently showed 0 messages when sqlite3 was not installed
or the DB query failed. Now logs a warning so operators can diagnose the
issue. Fixes #318.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-25 11:30:53 +08:00
chenhg5andClaude b91bb8388d feat(docs): enhance gitignore and revamp README with new banner and structure
generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-14 07:44:13 +08:00
chenhg5andClaude 8f630a0538 feat(commands): add support for exec commands with shell execution
Add ability to define custom slash commands that execute shell commands directly:
- Extend CommandConfig with Exec and WorkDir fields
- Add cmdCommandsAddExec handler for exec commands
- Implement executeShellCommand with timeout and output handling
- Add work_dir support for exec commands
- Update documentation and i18n messages
- Add tests and error handling

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-07 07:55:24 +08:00
chenhg5 c953bab72b build: release v1.2.0-beta.4 — streaming preview, typing indicators, markdown rendering, rate limiting
Made-with: Cursor
2026-03-06 11:04:54 +08:00
chenhg5 61b914dd2a chore: ignore RELEASE.md in gitignore 2026-03-02 16:14:55 +08:00
chenhg5andClaude dd0aa0c06b fix(gitignore): stop ignoring cmd/cc-connect/ directory
The pattern 'cc-connect' in .gitignore was matching directories at any
depth, which inadvertently excluded cmd/cc-connect/. Changed to
'/cc-connect' to only match the binary at the repo root.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-01 11:10:13 +08:00
chenhg5andClaude ecd0e0070f feat(claudecode): refactor agent into persistent session model with permission handling and i18n support
This major refactor:

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-28 22:05:12 +08:00
chenhg5andClaude 87827e1d81 refactor(build): enhance build system with cross-platform support
Added cross-platform build targets in Makefile and updated .gitignore. Introduced version, commit, and build time tracking via LDFLAGS. Added clean dist directory target and organized build artifacts.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-28 12:59:22 +08:00
chenhg5andClaude 92164b38fb feat(claudecode): add session management and persistence support
Add session listing capability via Agent interface
Implement session persistence in SessionManager
Improve Feishu markdown formatting support
Add verbose logging and error handling
Clean up session switching logic
Support session resume via --resume flag
Add agent session metadata scanning

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-28 12:53:43 +08:00
chenhg5andClaude 3b097a80cb init
Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-28 10:38:24 +08:00