ZhenYi
64ca5eeea1
fix(room): improve AI label fallback to never show "Unknown AI"
...
Fallback chain: modelName -> short model ID (no provider) -> 'AI'
2026-04-28 11:01:51 +08:00
ZhenYi
8a6ec1f62f
fix(billing): add transaction isolation and fix race conditions
...
Critical fixes:
- Wrap balance updates in database transactions with SELECT FOR UPDATE
- Move history insert after balance validation to prevent orphaned records
- Use Decimal throughout to avoid silent conversion failures
- Prevent concurrent requests from causing negative balances
Tasks resolved:
- Task #4 : Silent Decimal conversion failures
- Task #5 : Missing transaction isolation (race conditions)
- Task #6 : History inserted before validation
2026-04-28 10:12:24 +08:00
ZhenYi
6edacbcdf2
fix(billing): track actual tokens in ReAct mode instead of hardcoded 0/0
...
- process_react now returns (String, i64, i64) tuple with token counts
- Extract token stats from rig Agent FinalResponse usage field
- Both streaming and non-streaming ReAct modes now bill correctly
2026-04-28 10:04:54 +08:00
ZhenYi
7f927a4b6b
fix(billing): pass real project_id instead of Uuid::nil() for cost calculation
2026-04-28 09:57:45 +08:00
ZhenYi
211cf0ee3e
fix(agent): calculate and record cost in ai_session table
...
- Add record_ai_session() helper calling billing::record_ai_usage()
- Replace all Set(None) cost/currency with actual calculated values
- Cost computed from model_pricing via Decimal precision
2026-04-28 09:50:44 +08:00
ZhenYi
7b43f55f41
refactor(fctool): add descriptions to tools and simplify model sync
...
- Add description field to all fctool file and git tools
- Simplify extract_model_name in sync.rs (use upstream id directly)
2026-04-28 09:43:15 +08:00
ZhenYi
da2853d0ec
fix(blob): use TextDecoder for proper UTF-8 decoding
...
- atob() returns Latin-1 binary string, not UTF-8
- Chinese characters decoded incorrectly causing mojibake
- Use TextDecoder("utf-8") with Uint8Array for correct handling
2026-04-28 09:42:52 +08:00
ZhenYi
21d0d1eae6
fix(commits): compute total count on cache miss for pagination
...
- git_commit_log now computes count when Redis cache misses
- Previous: returned total: 0 when cache empty
- Now: compute + cache on miss (5min TTL)
2026-04-28 09:42:47 +08:00
ZhenYi
ddd24bfb6d
fix(streaming): add seq field for strict chunk ordering
...
- Add seq: u64 to RoomMessageStreamChunkEvent
- Frontend sorts by seq on insert for ordered replay
- Initial event now includes seq: 0
2026-04-28 09:42:41 +08:00
ZhenYi
5b3a6700be
refactor(agent): replace custom ReAct loop with rig::agent::Agent
...
- Use AgentBuilder for native tool-calling with stream_prompt()
- Add RecordingTool wrapper preserving retry + DB recording
- Fix tool_choice bug in do_completion (same as call_stream_once)
- Add seq field to RoomMessageStreamChunkEvent for strict ordering
- Map streaming events: Text→Answer, Reasoning→Thought, ToolCall→Action
- Only final event has done=true, removed premature stream ending
- Store __chunks__ JSON in thinking_content for ordered replay
2026-04-28 09:42:36 +08:00
ZhenYi
2bd40aee1b
fix(room): clear AI stream state on room switch and hide cursor for saved chunks
...
- Clear activeAiStream, streamingChunks, and timers when room changes
- Add showCursor prop to OrderedStreamChunks — only show cursor
during active streaming, not for saved content
2026-04-27 22:57:18 +08:00
ZhenYi
ab1ef0d1a7
feat(changelog): add /changelog page with i18n support
...
Create changelog page with language tabs (EN/CN/DE/FR),
timeline layout, and MDX rendering. Add generate script
to build changelog data from mdx files.
2026-04-27 21:59:50 +08:00
ZhenYi
7274aba6a1
feat(i18n): add German and French changelog translations
...
Create -de.mdx and -fr.mdx versions for all changelogs
(April 15-27, 2026) with proper translations.
2026-04-27 21:38:43 +08:00
ZhenYi
5be85c265b
feat(i18n): add German and French translation files
...
Translate all UI strings to German (Deutsch) and French (Français)
with proper technical terminology.
2026-04-27 21:31:01 +08:00
ZhenYi
72815a41c7
feat(i18n): complete translation file contents
2026-04-27 18:20:07 +08:00
ZhenYi
915c68e8e2
fix(sidebar): center notify icon and add user menu text when collapsed
2026-04-27 18:19:46 +08:00
ZhenYi
368b10d4e0
feat(i18n): integrate i18n into main.tsx, routes and settings page
2026-04-27 18:19:42 +08:00
ZhenYi
d05a13d7fc
feat(i18n): integrate LanguageSwitcher into landing nav and theme panel
2026-04-27 18:19:37 +08:00
ZhenYi
77e0923f28
feat(i18n): add LanguageSwitcher component and useLanguage hook
2026-04-27 18:19:32 +08:00
ZhenYi
a93a343d2b
chore(i18n): install i18next and react-i18next dependencies
2026-04-27 18:19:27 +08:00
ZhenYi
6aa56242db
feat(i18n): add translation files to public/locales
2026-04-27 18:19:20 +08:00
ZhenYi
74f38d0d42
feat(i18n): initialize i18n infrastructure
2026-04-27 18:19:10 +08:00
ZhenYi
9be635eaf3
docs(changelog): rewrite all changelogs in product language
...
- Unify title format: "Changelog — Month DD, YYYY" / "更新日志 — YYYY年M月D日"
- Remove internal tech details (frameworks, algorithms, migration names)
- Remove user-invisible bug fixes
- Reframe from engineering perspective to user benefits
- Consistent author: ZhenYi
2026-04-27 17:13:52 +08:00
ZhenYi
abc1c13343
docs(changelog): add April 15-17 changelogs (EN/CN)
...
Covering initial launch, landing pages, Redis message queue,
SSH clone URLs, model sync, room service improvements, and more.
2026-04-27 17:05:46 +08:00
ZhenYi
9b37f0a98a
docs(changelog): add April 26-27 changelogs (EN/CN)
...
- Public-facing changelogs covering AI built-in skills, security, and bug fixes
- English and Chinese versions for each date
- Author: ZhenYi
2026-04-27 16:47:46 +08:00
ZhenYi
2384ec792d
chore: update Cargo.lock with sha2 dependency for app crate
2026-04-27 16:42:24 +08:00
ZhenYi
bc7a5a6549
fix: resolve remaining warnings and fix API method name
...
- issue_triage.rs: use check_project_access instead of nonexistent get_project_member
- email/lib.rs: make EMAIL_REGEX pub to suppress dead_code warning
- tracing_fmt.rs: minor import ordering cleanup and code formatting
2026-04-27 16:42:01 +08:00
ZhenYi
afad0ab55d
feat(agent): implement built-in skills system (16 skills)
...
Add built-in skills with trigger-based activation system:
Git Operations:
- git-log: commit history analysis via git_log/git_graph/git_reflog
- git-diff: code changes analysis via git_diff/git_diff_stats/git_blame
- git-branch: branch management via git_branch_list/git_branch_info
- file-reader: file reading/search via git_file_content/git_grep
Code Quality:
- code-review: security/performance/quality checks
- code-explainer: explain complex code in accessible terms
Project Management:
- repo-manager: list/create/update repos
- issue-manager: manage issues with triage/labels/priorities
- board-manager: kanban boards and card management
- member-manager: team members and permissions
Development Productivity:
- pr-summary: generate PR summaries
- issue-triage: classify and prioritize issues
- doc-generator: generate README/API docs
- test-generator: write unit tests (AAA pattern)
- commit-message: generate conventional commits
Utilities:
- http-requester: HTTP requests and API testing
Skills integrated via PerceptionService with active/passive/auto triggers
Built-in skills automatically available to all projects
Database skills override built-in skills with same slug
2026-04-27 16:40:59 +08:00
ZhenYi
e7a250357f
fix(room): add cascade deletes and fix QuerySelect trait import
...
- Import room_message_reaction, room_message_edit_history, room_notifications modules
- Fix room_message_edit_history: no Room column, use subquery via messages
- Change publish_project_room_event from Result to () handling
- Add QuerySelect import for limit() method in workers.rs
2026-04-27 16:40:28 +08:00
ZhenYi
65627a8662
fix(app): fix session key to use SHA-512 (64 bytes)
...
cookie::Key requires exactly 64 bytes, SHA-256 only produces 32 bytes
Change to SHA-512 and slice to 64 bytes for correct key length
2026-04-27 16:40:20 +08:00
ZhenYi
e022240757
feat(agent): model sync improvements - deduplication and offline status
...
- Add Offline status to ModelStatus enum
- Sync marks all models offline first, then activates found ones
- Deduplicate by model name (ignoring provider)
- Deactivate orphaned models (offline -> deprecated)
- Add models_offline and models_deactivated to SyncModelsResponse
- Add deduplicate_existing_models() for cleanup
- Rename upsert_model to upsert_model_by_name
2026-04-27 16:40:10 +08:00
ZhenYi
52a0131b56
fix(git): LFS token validation and remove IP rate limiting
...
- Implement proper token validation via user_token table (SHA256+base64 hash)
- Query token_hash, check IsRevoked, validate expiry
- Remove IP-based rate limiting (handled by k8s ingress)
- Remove unused client_ip() helper function
- user_uid() now async and queries database for real user
2026-04-27 16:40:01 +08:00
ZhenYi
ef529d772b
fix(service): resolve backend compilation errors
...
- access_key.rs: use rand::rng() and random_range() for rand 0.10 API
- access_key.rs: fix update() returns DbErr, add .map_err(AppError::from)
- sync.rs: upsert_provider expects &str not String
- sync.rs: add QueryOrder import for order_by_asc
- issue.rs: change %e to ?e for Debug trait instead of Display
- workspace/info.rs: add missing closing brace in struct literal
2026-04-27 16:39:52 +08:00
ZhenYi
1deea4c671
fix(frontend): resolve TypeScript type errors in repository pages
...
- commits.tsx: fix Unix timestamp (time_secs) not multiplied by 1000
- RoomMessageSearch.tsx: add explicit generic type for resp.data
- RoomPinPanel.tsx: make sender_id optional (string | null)
- message-list.tsx: remove unused index variable in map
- repository-context.tsx: use correct RepoInfo field names
- use-audio-recording.ts: use audioStream state instead of undefined var
- universal-ws.ts: rename unused id to _id
2026-04-27 16:39:43 +08:00
ZhenYi
88dd3a5f61
fix: log silently dropped errors in compaction and SSH path handling
...
- Add tracing::warn! when conversation compaction fails (was let _ = e)
- Add tracing::debug! when SSH path canonicalize fails (was let _ = e)
2026-04-27 14:01:25 +08:00
ZhenYi
6a123170a1
fix: harden session key derivation from APP_SESSION_SECRET
...
- Reject secrets shorter than 32 bytes (fall back to generated key)
- Use SHA-256 hash instead of naive byte cycling to derive the key
(cycling "password" to 64 bytes gave extremely low entropy)
2026-04-27 13:59:31 +08:00
ZhenYi
0a272ed63a
fix: start SSH rate limiter cleanup and fix ToolContext reset per tool call
...
- Start SSH rate limiter cleanup task that was missing (prevent memory leak)
- Create single ToolContext outside tool execution loop so max_tool_calls
and max_depth guards actually fire across batch tool calls (was creating
fresh context per call, bypassing all limits)
2026-04-27 13:57:47 +08:00
ZhenYi
09645d8641
fix: resolve multiple bugs across backend and frontend
...
Security fixes:
- Remove WS token from plaintext log output (ws_universal.rs)
- Replace weak LCG PRNG with rand::thread_rng() for access key generation
- Add project membership check to issue triage endpoint (prevent unauthorized AI usage)
- Validate deepLinkUrl to prevent javascript: navigation (XSS defense-in-depth)
Data integrity fixes:
- Fix UUID truncation in AI model sync (as_u128() as i64 -> timestamp_millis)
- Wrap PR cascade delete in database transaction
- Add missing cascade deletes for room_message_reaction, room_message_edit_history, room_notifications
- Fix N+1 query for last_commit_times (single grouped query instead of per-repo)
Panic prevention:
- Replace unwrap() with safe fallbacks in health/metrics endpoints (email, git-hook apps)
- Replace unwrap() in access key scopes serialization
- Replace expect() in tool executor result map with synthetic error
- Replace expect() in log level parsing with default fallback
Logic bugs:
- Fix users_online metric double-decrement (decrement only when count reaches 0)
- Fix Map iteration + deletion bug in universal-ws.ts onclose handler
- Fix stale audioStream reference in catch block (use local stream variable)
- Add missing reInit event cleanup in carousel.tsx
- Fix email retry backoff integer overflow ((1 << i) as u64 -> 1u64 << i)
React fixes:
- Use message.id instead of index as key in message-list
- Add audio stream cleanup on unmount in use-audio-recording
2026-04-27 13:54:21 +08:00
ZhenYi
f36f08e3c4
fix: remaining unwrap panics and new bugs discovered during audit
...
- email worker: replace Mailbox::parse().unwrap() with match to
handle invalid recipient addresses gracefully
- metrics middleware: RwLock poison recovery on read/write locks
to prevent panic on thread panic
- access key: SystemTime::now() unwrap_or_default instead of unwrap
for clock-before-epoch edge case
- chpc: NaiveDateTime and_hms_opt unwrap_or MIN/MAX fallbacks
- push notification: second code path fixed for let-chain unwrap
- ai_streaming: constant UUID parse use expect() instead of unwrap
2026-04-27 11:30:01 +08:00
ZhenYi
df42af2ed0
fix: remaining push notification unwrap in second code path
...
- Fix second copy of push_subscription unwrap that was in a
tokio::spawn block with different indentation
- Replace constant UUID parse unwrap with expect()
2026-04-27 11:23:48 +08:00
ZhenYi
68b70330b8
docs: mark all 38 bugs as resolved in audit report
2026-04-27 11:21:13 +08:00
ZhenYi
cce9d216b8
fix: resolve 4 remaining "design decision" bugs
...
- SSH rate limiter: wire SshRateLimiter into SSHServer with IP-based
rate limiting on new_client connections
- Room startup: cap initial room load at 1000 via limit() to prevent
resource exhaustion on large instances
- WS token exposure: only include token in URL for cross-origin
connections; same-origin web clients authenticate via secure cookies
- CSRF: confirmed SameSite::Lax + Secure + HttpOnly are all set
(session config defaults)
2026-04-27 11:20:38 +08:00
ZhenYi
763d47dc45
fix: silent AI billing failures — add tracing::warn for billing errors
2026-04-27 11:15:15 +08:00
ZhenYi
1e975c0837
fix: regex injection in message search + semaphore expect panic
...
- Escape regex special chars in highlightText to prevent ReDoS
- Replace semaphore.acquire().expect() with graceful skip
- Add toast error feedback for search failures
- Remove unsafe (resp.data as any) bypass
2026-04-27 11:12:26 +08:00
ZhenYi
2842a62d35
docs: update bug audit report with fix status
2026-04-27 11:02:57 +08:00
ZhenYi
e96bb29434
fix: additional bugs - push notification unwraps and as any cleanup
...
- Replace Option::unwrap() with let-chains for push subscription fields
- Remove unsafe (repo as any).branch_count access in settings
2026-04-27 11:01:59 +08:00
ZhenYi
bdb5393835
fix: resolve 30+ bugs from security audit
...
Critical:
- CORS: replace allow_any_origin + credentials with env-configured origins
- XSS: escape HTML before dangerouslySetInnerHTML in search results
- Path traversal: sanitize storage keys to reject ".." components
- Auth missing: add Session requirement to git init/open/is-repo endpoints
- Transaction: wrap issue cascade delete in DB transaction
High:
- Mutex poisoning: replace unwrap() with poison-recovering guards
- Drop tokio::spawn: use runtime handle or fallback thread for lock release
- Redis KEYS: replace with non-blocking SCAN for typing events
- SSH panic: handle missing stdin/stdout/stderr gracefully
- LFS auth: remove x-user-uid header injection vector, generate per-request tokens
Medium:
- Memory leak: remove Box::leak in provider normalization
- Race conditions: query closed count directly instead of subtraction
- Silent failures: add tracing::warn for AI tasks, room events, activity logs
- Frontend nav: sync activeRoomId when initialRoomId prop changes
- Duplicate nav: remove redundant setActiveRoom in delete handler
- Callback conflict: skip undefined values in updateCallbacks merge
- Stale closure: use wsClient state instead of wsClientRef.current in useMemo
Low:
- Captcha: validate captcha not empty before login submission
- Broadcast capacity: reduce from 100K to 1000
- Error handling: add try/catch for removeMember and updateMemberRole
- Loading state: show placeholder instead of null in RepositoryContextProvider
- WebSocket: add heartbeat ping and jitter to reconnect backoff
2026-04-27 10:57:23 +08:00
ZhenYi
0f441f5eb4
fix(docker): use ubuntu:24.04 base image for all runtime Dockerfiles
...
CI / Rust Lint & Check (push) Has been cancelled
CI / Rust Tests (push) Has been cancelled
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
Resolves GLIBC_2.39 mismatch error — CI builds on ubuntu-latest
(24.04) which links against glibc 2.39, but debian:bookworm-slim
only provides glibc 2.36, causing binary execution failure.
2026-04-27 09:42:02 +08:00
ZhenYi
3f1f0d5e23
chore(service/git): minor fixes in service layer git operations
...
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
Small adjustments to commit, init, refs, star, and watch operations
in the service layer.
2026-04-27 08:28:27 +08:00
ZhenYi
64dc27161b
chore(git): minor fixes and improvements across git library modules
...
Apply small fixes across multiple git ops files: handle errors, improve
type safety, and refine HTTP handler and SSH git operations.
2026-04-27 08:28:09 +08:00