Commit Graph
789 Commits
Author SHA1 Message Date
viettranx 8beb72039c feat(desktop): add language switcher to onboarding setup screen
Add centered language toggle (EN/VI/中文) at top of setup wizard.
Default language changed from English to Vietnamese.
2026-03-27 23:53:17 +07:00
viettranx b373561f72 fix(desktop): fetch up to 100 releases to find lite-v* tags
GitHub API returns 30 releases by default. With 30+ v2.x releases,
lite-v* tags were pushed out of page 1 causing "No desktop release
found" error.
2026-03-27 23:44:59 +07:00
viettranx e1b8217e45 fix(desktop): keep PowerShell window open on install errors
Add Exit-WithPause helper that waits for keypress before closing the
window, so users can read error messages when fetch/download fails.
2026-03-27 23:37:06 +07:00
viettranx d9087fd0b7 fix(security): harden MCP bridge tenant_id propagation
- Guard uuid.Nil before converting to string in loop.go to avoid
  sending zero UUID as X-Tenant-ID header when no tenant is set
- Return (ok, tenantVerified) from VerifyBridgeContext so callers
  only inject tenant_id when HMAC actually covers it (level 1)
- Add unit tests for SignBridgeContext and VerifyBridgeContext
  including security test for tenant injection via HMAC fallback
2026-03-27 23:23:14 +07:00
mikedoandadmin 6551c2d1e2 fix: propagate tenant_id through MCP bridge for memory indexing (#512)
Problem:
Memory documents saved via write_file → MemoryInterceptor are stored
in memory_documents (PutDocument succeeds via fail-open tenant fallback),
but IndexDocument fails with "tenant_id required" because the MCP bridge
chain never propagates tenant_id. This results in 0 memory_chunks,
making memory_search return empty for all agents using claude_cli provider.

Root cause:
- BridgeContext struct lacks TenantID field
- writeMCPConfigInternal never sets X-Tenant-ID header
- bridgeContextMiddleware never extracts/injects tenant_id into context
- PutDocument uses tenantIDForInsert() (fail-open, defaults to master)
- IndexDocument uses scopeClause() → requireTenantID() (fail-closed)

Fix:
- Add OptTenantID constant and BridgeContext.TenantID field
- Pass tenant_id from agent loop context → provider opts → MCP headers
- Add X-Tenant-ID to bridge request headers (HMAC-signed)
- Extract X-Tenant-ID in bridgeContextMiddleware → store.WithTenantID()
- Backward-compatible HMAC verification with 3 fallback levels
  (with tenant, without tenant, without workspace+tenant)

Affected: all agents using claude_cli provider type.
Also fixes: "KG embeddings backfill failed: tenant_id required"

Co-authored-by: admin <admin@admins-MacBook-Pro.local>
2026-03-27 23:20:07 +07:00
viettranx f4f050bcd4 fix(desktop): increase media thumbnail height from 160px to 288px
Change from h-40 object-cover (fixed crop) to max-h-72 object-contain
so images display at proper aspect ratio without cropping.
2026-03-27 23:00:16 +07:00
viettranx 0b8366bfd0 fix(agent): raise default compaction threshold from 75% to 85%
Compaction was triggering too early because prompt tokens include
system prompt + context files + tools, not just history. Raising
the threshold reduces unnecessary compaction cycles.
2026-03-27 22:55:59 +07:00
viettranx ee9f5b8aaf feat(team): share leader memory with team members (read-only)
Team members dispatched via team tasks can now read the leader's memory
files (MEMORY.md, memory/*.md) as a fallback when they have no own
memory. Memory writes are blocked for members — only the leader can
save memory files. This follows the existing team_workspace context
propagation pattern: dispatch metadata → RunRequest → context → tools.

Affected tools: read_file (interceptor), memory_get, memory_search,
list_files (interceptor). All include leader fallback with per-user →
global scope cascade.
2026-03-27 22:45:40 +07:00
viettranx e9342533e0 refactor(tools): extract TeamToolBackend interface for team task testability
Extract TeamToolBackend interface from concrete *TeamToolManager to enable
unit testing of the 17 team task action handlers without DB or message bus.

- Add TeamToolBackend interface (19 methods) in team_tool_backend.go
- Add exported wrappers on TeamToolManager (cache, helpers, dispatch, manager)
- Migrate 133 call sites across 5 action handler files (pure casing rename)
- Change TeamTasksTool.manager field from *TeamToolManager to TeamToolBackend
- Add mock backend infrastructure (baseNoopTeamStore + mockTaskStore + mockBackend)
- Add 94 unit subtests across 6 test files covering all actions:
  lifecycle (claim/complete/cancel/review/approve/reject),
  create validation, blocker escalation, mutations (comment/progress/attach/update),
  followup (ask_user/clear_ask_user/retry), read actions (notification/policy/list/search/get)

WorkspaceInterceptor and PostTurnProcessor remain on concrete *TeamToolManager.
No behavioral changes — all existing logic preserved.
2026-03-27 22:26:36 +07:00
Thieu Nguyen c0dfea35ea fix(ui): show env var input section for manual CLI credentials (#514)
When adding a CLI credential with "Manual (no preset)" mode, the env var
input section was hidden because it only rendered when a preset was
selected. Add a dynamic key-value form allowing users to define custom
environment variables for non-preset CLI tools.

Closes #477
2026-03-27 21:50:31 +07:00
Luan VuandLuvu182 be9044ca8e fix(zalo): update API version, batch group fetch, fix WS decrypt (#516)
- Bump DefaultAPIVersion from 665 to 671 to match current Zalo web client
- Batch getmg-v2 requests (50 groups/batch) — Zalo rejects large payloads,
  causing error 114 for accounts with many groups (e.g. 250+)
- Fix encryptType=1 WebSocket event decryption: add gzip decompression
  after base64 decode (matches zca-js pako.inflate behavior)
- Split contacts picker into Friends/Groups tabs for better usability

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-27 21:50:01 +07:00
viettranx e297fb63b8 ci(release): add pnpm/node cache to desktop release workflow
Replace corepack-only pnpm setup with pnpm/action-setup@v4 + actions/setup-node@v4
with cache enabled. Saves ~30-60s per build by caching pnpm store.
2026-03-27 21:06:53 +07:00
viettranx 7f796b0120 fix(agent): channel-aware tool filtering, group chat title in system prompt
- Add filteredToolNamesForChannel() so system prompt Tooling section
  excludes channel-specific tools for wrong channels (e.g. list_group_members
  hidden for Telegram, create_forum_topic hidden for Feishu)
- Add ChannelAware interface to CreateForumTopicTool (Telegram-only)
- Add coreToolSummaries for list_group_members and create_forum_topic
  (were showing as "(custom tool)")
- Inject group chat title into system prompt identity line
  (e.g. "telegram (group chat \"My Group\")" instead of "a group chat")
- Sanitize ChatTitle to prevent prompt injection (strip quotes/newlines,
  truncate to 100 chars)
2026-03-27 21:03:34 +07:00
viettranx 8b08dec04c fix: address code review findings (critical + high + medium)
Critical:
- retryOnBusy: return lastErr after exhausted retries instead of nil

High:
- Remove debug console.log from use-paired-devices.ts

Medium:
- ChannelGeneralTab: sync state from instance prop via useEffect
- i18n: add MsgCannotRemoveLastWriter key + translations (en/vi/zh)
- use-channel-crud: refetch after delete instead of optimistic remove
2026-03-27 20:53:05 +07:00
viettranx 5f5b0c45bd fix(telegram): inject tenant_id into command handler context
All Telegram bot commands (/writers, /addwriter, /removewriter, /reset,
/tasks, /task_detail) and callback queries were missing tenant_id in
context, causing "tenant_id required" errors from scopeClause() or
silent fallback to MasterTenantID breaking multi-tenant isolation.
2026-03-27 20:44:27 +07:00
viettranx 0b3be862c9 fix(desktop): fix pairing time scan, i18n keys, convert advanced to tab
SQLite pairing:
- Fix rows.Scan failing on Go time.Time strings with monotonic suffix
- Scan timestamps as strings, parse with parseTimeToMillis() that strips m=+
- Use time.Now().Round(0) for all SQLite time comparisons
- Wire SetOnRequest for SQLite store via interface assertion (not PG-only)

Desktop UI:
- Fix ChannelManagersTab i18n keys: managers.xxx → detail.managers.xxx
- Fix ChannelAdvancedDialog i18n keys and save logic (wrap in config)
- Convert Advanced from modal dialog to inline tab (4th tab)
- Add "advanced" tab label to all 3 locale files
2026-03-27 20:44:12 +07:00
viettranx 2ba883aff7 fix(pairing): broadcast pairing events for SQLite stores, not just PG
SetOnRequest was only wired for PGPairingStore via concrete type assertion.
Use interface-based assertion so SQLitePairingStore also gets the callback.
This fixes desktop app not receiving real-time pairing request notifications.
2026-03-27 20:27:25 +07:00
viettranx 0a8ca13d08 refactor(http): standardize error responses with writeError helper
- Create response_helpers.go with writeError(w, status, code, msg) for structured errors
- Move writeJSON to response_helpers.go for co-location
- Migrate agents.go, channel_instances.go, api_keys.go to writeError with protocol error codes
- Replace raw err.Error() with i18n messages + slog.Error for debugging
- Fix channel creation: map camelCase input to snake_case for backend HTTP API
- Fix PairedDevicesSection reload button: use RefreshButton component
2026-03-27 20:15:26 +07:00
viettranx 6ea9b4d762 feat(desktop): add channel management, paired devices, and multiple fixes
Channel Management:
- Add Channels settings tab with full CRUD for Telegram/Discord (Lite: max 1 each)
- Channel detail panel with tabs: General, Credentials, Managers
- Advanced settings dialog (network, limits, streaming, behavior, access control)
- Schema-driven field renderer with Combobox selects, Switch toggles
- Paired Devices section: approve/deny pending, revoke paired, WS event auto-refresh
- Pairing notification badge in sidebar footer with pending count
- i18n support (en/vi/zh) for all channel strings

Bug Fixes:
- Fix Vietnamese slug generation (NFD normalize + đ/Đ handling) in lib/slug.ts
- Make agent key field editable instead of read-only
- Fix trace detail input/output: use MarkdownRenderer with copy button instead of forced-dark CodePreview
- Fix API error parsing to handle both {error: "string"} and {error: {message}} formats
- Add Accept-Language header to desktop API client for i18n error messages
- Wrap raw err.Error() with i18n messages in HTTP handlers (agents, channel_instances)
- Increase SQLite MaxOpenConns from 2 to 4 to reduce SQLITE_BUSY contention
- Add retryOnBusy wrapper for context file seeding writes
- Update EditionCompareModal: channels moved from "false" to "1 Telegram + 1 Discord"
2026-03-27 19:52:28 +07:00
viettranx 2bc0f5f14a fix(telegram): prevent duplicate messages in groups when streaming disabled
When group_stream=false (default), channels implementing StreamingChannel
still processed chunk events, creating stream messages alongside block
replies — causing each intermediate message to appear twice.

Gate the streaming handler on rc.Streaming so it only activates when
streaming is actually enabled for the run.
2026-03-27 19:49:33 +07:00
viettranx d3bf16d2de refactor(bootstrap): separate profile and seeding callbacks, consolidate per-user state
- Split EnsureUserFilesFunc into EnsureUserProfileFunc (profile + workspace)
  and SeedUserFilesFunc (context file seeding) for single-responsibility
- Merge userWorkspaces + userFilesSeeded sync.Maps into unified userSetups
  struct to prevent desync between workspace and seeding state
- Add skipIfAnyExist param to SeedUserFiles to encapsulate the
  "seed only for brand-new users" logic within the bootstrap package
- Extract getOrCreateUserSetup helper for clean per-user initialization
- Add bootstrap state tests covering all 4 system prompt branches
- Keep legacy EnsureUserFilesFunc as fallback for backward compatibility
2026-03-27 19:16:31 +07:00
viettranx 23c43259c9 fix(bootstrap): ensure per-user context files are seeded for all agent types
- Separate file seeding from workspace resolution so agents without
  workspace still get BOOTSTRAP.md and USER.md seeded
- Always seed context files for existing profiles that have zero files
  (handles EnsureUserProfile pre-creation via HTTP API)
- Add persistent "USER PROFILE INCOMPLETE" nudge in system prompt when
  BOOTSTRAP.md is cleaned up but USER.md remains blank
- Move bootstrap auto-cleanup nudge before session flush so the reminder
  is persisted to history
- Add userFilesSeeded sync.Map to avoid redundant seeding calls
- Capture workspace from seeding call to eliminate double DB roundtrip
2026-03-27 18:19:53 +07:00
viettranx 343ad0c2b1 fix(ui): remove USER_PREDEFINED from summoning, refine canvas dots, require team members
- Remove USER_PREDEFINED.md from summoning file list (web + desktop)
- Soften canvas-dots pattern (smaller dots, wider spacing)
- Require at least 1 member when creating a team
- Prevent removing the last non-lead member from team
2026-03-27 18:01:00 +07:00
viettranx 39ffe6e78f fix(teams): update post-turn comment to match simplified auto-complete logic 2026-03-27 17:18:43 +07:00
viettranx 3c1baecef5 feat(desktop): add Storage management tab in Settings
Browse, upload, download, move, and delete workspace files from the
desktop app. File tree with drag-and-drop move (@dnd-kit/core), syntax
highlighting (react-syntax-highlighter), markdown/CSV/image viewers,
upload dialog with drag-drop + validation, and SSE storage size streaming.
2026-03-27 17:16:29 +07:00
viettranx 5ed86b84c0 fix(teams): simplify post-turn task action fallback to auto-complete
The case expression `taskActionFlags.Progressed || ...` always evaluates
to `true/false`, never matching the switch value. Merge it into the
default branch so non-terminal actions consistently auto-complete.
2026-03-27 17:16:16 +07:00
viettranx 22dc87a262 fix(desktop): move version into Lite badge, remove check update button 2026-03-27 15:59:42 +07:00
viettranx 2f31db4c7e fix(vision): restore context fallback for read_image in file-ref mode
PR #511 removed WithMediaImages context in file-ref mode, breaking
read_image when LLM omits the path param. Restore base64 context as
fallback (costs Go memory, not LLM tokens). Also improve error messages
to distinguish missing provider config vs provider failures.
2026-03-27 15:59:42 +07:00
viettranx 7eea004c8d fix(bootstrap): predefined agents now reliably complete USER.md onboarding
- Strengthen FIRST RUN prompt: mandatory write_file calls, no deferring
- Filter BOOTSTRAP.md from system sessions (subagent/cron/heartbeat)
- Remove duplicate bootstrap reminder in buildProjectContextSection
- Fix template: proper tool-calling syntax, step-by-step instructions
2026-03-27 15:59:42 +07:00
Thieu Nguyen 30bf66d1da fix(docker): remove manual network creation causing Compose label mismatch (#513)
The Makefile `net` target creates goclaw-net via `docker network create`
without the `com.docker.compose.network` label. Docker Compose then rejects
the network on macOS Docker Desktop. Compose already manages this network
automatically with correct labels.

Closes #488
2026-03-27 15:58:34 +07:00
Duy /zuey/ 231bc9684e fix(vision): file-ref mode + media pipeline fixes for image visibility (#511)
* fix(vision): file-ref mode + media pipeline fixes for image visibility

Replace inline base64 image loading with file path references when
read_image provider is configured. LLM calls read_image(path=...)
instead of receiving 25K-250K tokens of base64 per image.

Changes:
- Agent loop: skip base64 context storage in file-ref mode, only
  load historical images for inline fallback
- New enrichImagePaths() enriches ALL user messages with file paths
  (not just current turn) so historical images are accessible
- System prompt: imperative tool summaries ("REQUIRED when you see
  <media:image> tags") + dedicated "Media Files" section
- Slack: store mediaPaths in pending history + CollectMedia on mention
- Feishu: add CollectMedia for group context history media
- RC-1 fix: save enriched content (with media IDs/paths) to DB
  instead of raw req.Message

Closes #509

* fix(vision): resolve Claude review — Feishu early media + skip loadImages in file-ref mode

- Feishu: download media BEFORE mention gate (step 4) and store file
  paths in pending history via Media field. Reuse early-resolved
  MediaInfo at step 10 to avoid double-download. CollectMedia now
  returns actual paths instead of empty.
- Agent loop: guard loadImages() behind !deferToReadImageTool so
  file-ref mode avoids unnecessary disk I/O + base64 encoding.
2026-03-27 14:20:05 +07:00
Kai (Tam Nhu) Tran 4dafd70c83 fix(ui): stop logout on method-level UNAUTHORIZED, align TTS route guard (#502)
ws-client.ts treated any UNAUTHORIZED WebSocket response as session
invalidation, triggering full logout. This caused clicking the TTS tab
to log users out because config.get requires owner role while the route
only required admin.

- Remove UNAUTHORIZED from onAuthFailure trigger in handleResponse;
  only TENANT_ACCESS_REVOKED forces logout now
- Change TTS route guard from RequireAdmin to RequireOwner (matches
  backend requireOwner on config.get/config.patch)
- Gate TTS sidebar item behind isOwner so non-owners don't see it

Closes #501
2026-03-27 13:43:25 +07:00
Luan VuandLuvu182 9e74974129 fix: feishu reply context truncation + task events NULL data crash (#508)
* fix(feishu): increase reply context max length from 500 to 2000

500 bytes is too short for CJK/Unicode text (each accented char = 2-3
bytes, so ~250 real characters). Increase to 2000 so reply context is
not aggressively truncated.

* fix(teams): handle NULL data column in task events queries

ListTaskEvents and ListTeamEvents crash with "unsupported Scan,
storing driver.Value type <nil> into type *json.RawMessage" when the
data column is NULL. Use COALESCE(data, '{}') to return an empty JSON
object instead.

---------

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-27 13:42:31 +07:00
viettranx 1efec43df0 feat(desktop): show version + check update button in sidebar header 2026-03-27 13:37:38 +07:00
viettranx 2c94e8070f fix(desktop): image rendering for Windows paths and MEDIA: prefix
- toFileUrl: normalize backslashes, detect Windows drive-letter paths
- resolveFileUrl: strip MEDIA: prefix from tool results, Windows path support
- handleServe: skip prepending "/" for Windows drive-letter URL paths
2026-03-27 13:07:14 +07:00
viettranx 0292440c35 fix(desktop): make update banner action buttons easier to click 2026-03-27 12:33:10 +07:00
viettranx 622e405436 fix(desktop): default theme to light mode for fresh installs 2026-03-27 12:29:06 +07:00
viettranx 4102d4f321 fix(scripts): auto-launch app after install on macOS and Windows 2026-03-27 12:23:29 +07:00
viettranx 07f43cad36 fix(teams): persist leader media as DB attachments on task creation
Leader-created tasks copied media files to workspace and stored paths
in task metadata, but never inserted into team_task_attachments table.
Members got auto-attached via WorkspaceInterceptor context, but leaders
don't run inside a task context. Now explicitly call AttachFileToTask
after CreateTask succeeds. Dedup handled by ON CONFLICT DO NOTHING.
2026-03-27 12:18:01 +07:00
viettranx 5e936ebf8f feat(desktop): team settings modal, task detail attachments, shared icons
- Add TeamSettingsModal: editable name/description, member management
  (add/remove with minimum 1 member guard), notification toggles (5 events
  + direct/leader mode)
- Extend backend teams.update to support name/description fields
- Add gear button + "+" info button to team board header
- Task detail modal: fetch full detail with attachments on open,
  render attachment list with download links (resolved against local gateway)
- Chat view TaskPanel: clicking active tasks opens TaskDetailModal
- KanbanCard: show comment and attachment counts
- Extract 14 shared SVG icons to Icons.tsx, replace all inline SVGs
  in team components (0 remaining)
- Extract TERMINAL_STATUSES and TeamNotifyConfig to shared types
- i18n: en/vi/zh settings, members, notification, attachment keys
2026-03-27 12:18:01 +07:00
viettranx 865f724816 fix(team): improve leader task decomposition guidance for weaker models
Add concrete task sizing rules, skill-based split tests, and 3 decomposition
examples to TEAM.md so non-Claude leaders (Qwen, GPT, MiniMax) create
appropriately scoped tasks instead of monolithic ones. Soft warning in create
response when subject suggests compound deliverables.
2026-03-27 12:12:03 +07:00
viettranx 1c2dd4f1dd fix(gateway): resolve tenant switch mismatch for non-owner users
Non-owner tenant switch set only tenant_hint in localStorage, but WS
Path 1 non-owner and HTTP client only read tenant_id — causing silent
fallback to MasterTenantID.

Frontend: always set TENANT_ID on switch; keep TENANT_HINT for pairing compat.
Backend: WS Path 1 non-owner now falls back to TenantHint before deprecated TenantScope.
2026-03-27 12:07:14 +07:00
viettranx 9d2aeb7c9c fix(sqlitestore): add ListCodexPoolSpans stub for TracingStore interface 2026-03-27 10:50:55 +07:00
viettranx 6de054df33 build: update frontend asset references in index.html and add it to .gitignore. 2026-03-27 10:44:43 +07:00
viettranx f9f63f12a1 docs: update agent teams Section 7 to match task dispatch flow
Replace outdated spawn+team_task_id delegation docs with current
team_tasks(create, assignee) + dispatchTaskToAgent() auto-dispatch model.
2026-03-27 10:43:29 +07:00
viettranx ffb6786ea4 feat(telegram): lazy-resolve media from pending history on mention
When users send media in a group without mentioning the bot, store
Telegram file_ids as lightweight MediaRef in history entries (no
download). When the bot is mentioned, resolve refs by downloading
media and including them in the LLM context.

Safeguards: 5 MB file size cap, max 15 refs per mention, 30s batch
timeout. Mirrors existing CollectMedia pattern from Discord/Zalo.
2026-03-27 10:39:10 +07:00
viettranx 1fdc4d3228 fix(ci): use macos-14 for both arch builds (macos-13 deprecated) 2026-03-27 10:38:42 +07:00
viettranx 65e7eb8a5f docs: add wails dev command to CLAUDE.md 2026-03-27 10:34:58 +07:00
viettranx c43cd0fb5d docs: add desktop edition notes to CLAUDE.md
Desktop tech stack, build commands, edition system, WS param naming,
auto-update flow, release process, lite limits, tool gating, file
serving security model. Add sqliteonly build check to post-impl checklist.
2026-03-27 10:33:24 +07:00
viettranx c2cb37afcf fix(desktop): improve Windows install script error handling
- SilentlyContinue progress preference (10x faster download)
- try/catch on API + download calls with colored error messages
- Non-fatal shortcut creation (works without admin)
- Colored output for better UX
2026-03-27 10:32:10 +07:00