7 Commits

Author SHA1 Message Date
zkpaiminmin 96ec9b89cc docs: translate Chinese comments and JSDoc to English across 14 files
Standardize code documentation language to English for better international
collaboration, covering ai-bridge services, Java backend, webview scripts,
and frontend utilities.
2026-03-17 19:16:38 +08:00
朱昆鹏 e6fd7e677a Feature/v0.2.4 (#513) (#536)
* feat: replace remote SDK slash command fetching with local registry

Move slash command loading from async SDK API calls to fully local
parsing of skill directories and built-in command lists.

- Add SkillFrontmatterParser to parse SKILL.md YAML frontmatter with
  SafeConstructor (prevents deserialization attacks)
- Add SlashCommandRegistry to merge built-in + user skill/command lists
  per provider with name-based deduplication
- Claude: scan ~/.claude/commands/, ~/.claude/skills/ (personal) and
  {cwd}/.claude/commands/, {cwd}/.claude/skills/ (project)
- Codex: scan ~/.codex/prompts/ only (Codex skills use $ prefix and
  are NOT slash commands — $ skill scanning is not yet implemented)
- Support optional name (falls back to directory name), optional
  description (falls back to first markdown paragraph), and
  user-invocable: false filtering
- Refresh slash commands on provider switch via SettingsHandler
- Add SnakeYAML 2.2 dependency for frontmatter parsing

Remove dead remote slash command fetching code:
- Remove getSlashCommands() from message-service.js (~125 lines)
- Remove getSlashCommands case/import from claude-channel.js
- Remove getSlashCommands protocol comment from daemon.js
- Remove ClaudeSDKBridge.getSlashCommands() method and
  [SLASH_COMMANDS] tag parsing (two locations)
- Rewrite FileHandler.handleGetCommands() to use local registry
  instead of bridge call; note: the get_commands event from frontend
  may no longer be triggered since slash commands are now pushed
  proactively on session creation and provider switch
- Remove addFallbackCommands() which is no longer needed

* feat: add Codex skills support with multi-level scanning and config.toml integration

Add CodexSkillService for managing Codex skills with a different mechanism
from Claude skills:
- Directory-based skills under .agents/skills/ with multi-level upward scanning
- $ prefix invocation (via dollarCommandProvider) instead of /
- Enable/disable via ~/.codex/config.toml [[skills.config]] entries
- User (~/.agents/skills/, ~/.codex/skills/) and repo ({cwd}/.agents/skills/) scopes
- SKILL.md frontmatter parsing for metadata extraction

Key fixes from code review:
- Use path-stable id (scope:normalizedPath) to prevent same-named skills in
  parent/child directories from overwriting each other; child directory takes
  priority via first-hit-wins dedup
- Normalize paths on both read and write sides of config.toml toggle/cleanup
  operations to prevent Windows path separator mismatches
- Restrict Codex skill import to directories only (DIRECTORIES_ONLY chooser +
  server-side validation) since scans only recognize directory-based skills

Also includes frontend changes: SkillsSettingsSection dual-mode UI,
dollarCommandProvider for $ autocomplete, i18n updates for 8 locales,
and CodexSettingsManager for config.toml read/write.

* fix: resolve real OS home directory to bypass IDEA's user.home override

IDEA may set user.home to a custom path (e.g. E:/Untitled/IDEA-Jconfig),
causing config and session files to resolve under the wrong directory.

- Update PlatformUtils.getHomeDirectory() to read USERPROFILE (Windows)
  or HOME (Unix) env vars, falling back to System.getProperty("user.home")
- Replace all 35 direct System.getProperty("user.home") calls across 22
  Java files with PlatformUtils.getHomeDirectory()
- Add checkstyle rule NoUserHomeProperty to enforce the pattern going
  forward; PlatformUtils.java is excluded as the sole legitimate fallback

* fix: prevent stale loading panel blocking error UI on Node.js detection failure

When checkEnvironment() fails after bridge extraction (isExtractionComplete),
retryCheckEnvironmentWithBackoff showed a loading panel then invoked
showErrorPanel() asynchronously without clearing it, leaving the UI stuck.

- Extract replaceMainContent() helper: removeAll + add + revalidate + repaint
- Route all show*Panel() methods through replaceMainContent() so async invokeLater
  callbacks always replace stale content regardless of prior panel state
- Downgrade LOG.error to LOG.warn in checkEnvironment() to avoid triggering
  IntelliJ error notification system for an already-handled exception

* fix: resolve permission mode state desync between frontend and backend

Establish a unified permission mode flow with explicit priority rule:
payload.permissionMode > sessionMode > default.

Frontend changes:
- Remove duplicate window.onModeReceived registration in App.tsx; funnel
  all mode callbacks through useWindowCallbacks as the single entry point
- Pre-register onModeReceived placeholder in main.tsx to capture early
  backend pushes before React callbacks are ready, then replay on registration
- Add get_mode pull request after callback registration to guarantee
  eventual convergence even if the backend push was missed
- Apply idempotent setter guards to prevent redundant mode re-renders
- Propagate current permissionMode in every send_message and
  send_message_with_attachments payload; codex provider is forced to
  bypassPermissions on the frontend as well

Backend changes:
- Extract optional permissionMode from both send_message and
  send_message_with_attachments payloads in SessionHandler; validate
  against whitelist, ignore unknowns (backward compatible)
- Add new ClaudeSession.send() overloads accepting requestedPermissionMode
  without breaking existing call sites
- Implement resolveEffectivePermissionMode: codex always uses
  bypassPermissions; otherwise payload mode > session mode > "default"
- Pass effectivePermissionMode directly to ClaudeSDKBridge and
  CodexSDKBridge so the SDK executes with the mode the user selected
- Add volatile to SessionState fields (permissionMode, model, provider,
  reasoningEffort) to ensure cross-thread visibility between set_mode and
  send_message handlers

* refactor: extract token usage utilities from ClaudeMessageHandler

Move provider-aware token calculation and usage lookup methods
into a dedicated TokenUsageUtils class to decouple shared token
logic from Claude-specific message handling.

* feat(v0.2.4): improve process lifecycle and resource cleanup

- Add tab disposal handler to shut down daemon when tab is removed
- Collect windows from both instances and contentToWindowMap in shutdown hook
- Wait for process termination after destroyForcibly in DaemonBridge
- Forcefully kill unresponsive daemon in handleDaemonDeath
- Restore interrupt flag in InterruptedException catch blocks
- Fix resource leak: add bridge cleanup in all callback and exception paths
  for both Claude (shutdownDaemon) and Codex (cleanupAllProcesses)
- Rewrite claude-ps.mjs with tree display, PPID tracking and project detection
- Skip changelog.ts write when content unchanged
- Bump version to 0.2.4

* refactor: unify permission mode validation across frontend and backend

Extract duplicated permission mode whitelist into shared constants:
- Backend: SessionState.VALID_PERMISSION_MODES + isValidPermissionMode()
- Frontend: VALID_PERMISSION_MODE_IDS + isValidPermissionMode() type guard
- Remove private isValidPermissionMode() from SessionHandler
- Add volatile rationale comments to SessionState fields
- Downgrade ModeSync console.info to console.debug

* fix: remove changelog.ts auto-generation from build pipeline

Stop extract-changelog.mjs from running during prebuild to prevent
unintended modifications to changelog.ts on every build.

* fix: decouple status panel expanded state from content presence

Status panel expand/collapse is now driven solely by user preference,
allowing users to keep the panel expanded or collapsed regardless of
whether tasks, subagents, or file changes exist.

* fix: remove model ID format regex restriction

* refactor: move payment QR codes from README to SPONSORS.md

将支付宝、微信、PayPal 的赞助二维码从 README.md 和 README.zh-CN.md
移至 SPONSORS.md,保持 README 简洁并集中管理赞助信息。

* fix: harden Codex skills security and improve dollarCommandProvider robustness

- Validate skillPath in deleteSkill/toggleSkill to require SKILL.md filename
  and match skill name, preventing path traversal via crafted frontend input
- Add path traversal checks (.. and \0) in SkillHandler for delete/toggle
- Configure YAML parser with setMaxAliasesForCollections(10) and
  setCodePointLimit(8192) to prevent billion laughs DoS attacks
- Skip symbolic links during skill directory scanning
- Add LoadingState tracking to dollarCommandProvider with loading/error
  feedback, aligning with slashCommandProvider robustness
- Remove stray console.log from dollar commands pre-registration in main.tsx
- Add .exceptionally() handler to refreshSlashCommandsForProvider async task

* feat: add Qwen and OpenRouter provider presets

Add Alibaba Qwen and OpenRouter as new provider presets with
corresponding i18n translations for all supported languages.

* fix: improve tab title management for history sessions and manual renames (#527)

- Send rename_tab with force flag when loading history sessions so tab title updates from AI*
- Prevent manual tab renames from being overwritten by status indicators (ANSWERING/IDLE)
- Strip trailing "..." in setOriginalTabName to prevent double dots on truncated titles
- Add defensive external rename detection in updateTabStatus
- Auto-rename tab to first message text for new sessions
- Add claude.bridge.path system property to build.gradle for dev environment stability



* revert: remove auto tab rename features from PR #527, keep only tab title bug fixes

Reverted features:
- Auto tab title from first message (App.tsx)
- History session tab title sync (useSessionManagement.ts)
- rename_tab handler in TabHandler.java

Kept fixes:
- Manual rename no longer overwritten by AI status indicators
- Double ellipsis on truncated titles

* fix: allow symbolic links in Codex skill directory scanning

Remove the symbolic link skip check during skill scanning, so that
symlinked skill directories are properly discovered and loaded.

* fix: use local variable for tab name in status update

Replace direct mutation of originalTabName field with a local tabName
variable inside the lambda to avoid unintended side effects.

* docs: add new contributor Olexandr1904 and update contributor badges

* refactor: replace alert dialogs with toast notifications and inline feedback

* feat: highlight auto mode selector in bright orange for permission warning

Auto mode bypasses all permission checks, so apply a distinct orange
color to the mode selector button as a visual cue when it is active.

* fix: sync permission mode state in reused daemon runtime hooks

Use a shared mutable state object for permission mode in pre-tool-use
hooks so daemon runtimes that are reused across turns always read the
current mode instead of a stale value captured at creation time.

* docs: update contributor badge emoji from fire to star

* feat: add info notices and polish UI details

- Redesign app icon to simplified stroke-based SVG
- Tone down auto mode selector color to subtle amber
- Add security notice to provider dialog
- Add estimate disclaimer to usage statistics section
- Add shared notice-box styles (info/warning variants)
- Add i18n translations for notices across 8 languages

* fix: apply date range filter on server side for usage statistics (#534)

Previously, switching between "Last 7 Days", "Last 30 Days" and "All Time"
in the usage statistics panel only filtered the Timeline chart and Sessions
list on the front end, while the Overview totals (cost, sessions, tokens)
and Models tab always displayed all-time aggregated data.

Changes:
- Frontend: pass dateRange in the get_usage_statistics request payload and
  add it to the useEffect dependency array so a new request fires on every
  switch; remove unused optional range parameter from loadStatistics()
- SettingsHandler: parse dateRange ("7d" | "30d" | "all") and convert it to
  a cutoffTime timestamp (0 = no cutoff); hoist Gson instantiation to avoid
  duplicate declarations in each branch
- ClaudeHistoryReader.getProjectStatistics: accept cutoffTime, filter the
  session list before aggregation, use imported Collectors instead of fully
  qualified name
- CodexHistoryReader.getProjectStatistics: same cutoffTime parameter and
  filtering; remove redundant totalSessions assignment before filtering

* refactor: remove useUsageStats hook (#535)

The hook became a no-op after the background polling was removed.
Its only remaining effect was clearing window.updateUsageStatistics
on unmount, but it was called from the root App component which
never unmounts, so the cleanup never ran.

UsageStatisticsSection owns the full data lifecycle — it loads on
mount and reloads on scope/dateRange changes — so no dedicated hook
is needed.

* fix: harden input validation and fix UI issues

- Add skill name validation to prevent path traversal in SkillService
- Add path normalization and directory whitelist checks in SkillHandler
- Validate permission mode against whitelist in SessionState and daemon
- Properly re-interrupt thread on InterruptedException in DaemonBridge
- Add max-height and scroll to config select dropdown to prevent overflow
- Relax model ID validation to support third-party provider formats

* docs: add v0.2.4 changelog from PR #513 commit history

* chore: rename vendor from CodeMossAI to MossX

---------

Co-authored-by: Gadfly <gadfly@gadfly.vip>
Co-authored-by: Oleksandr Brazhenko <brazhenko.p@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-02 15:13:31 +08:00
zkpaiminmin 1fedd58bc4 feat(webview): make version tag clickable to open changelog dialog
Support clicking the version tag on the welcome screen to open the
What's New changelog dialog. Also fix changelog parser regex to
support two-segment versions like v0.2.
2026-02-20 00:57:52 +08:00
zkpaiminmin 3346c851d3 feat(webview): add changelog dialog and custom Claude model support
- Add version update notification dialog with pagination and i18n
- Add changelog extraction build script for CHANGELOG.md parsing
- Add custom model editor for Claude providers with localStorage sync
- Bump version to 0.1.9-fix
2026-02-19 11:22:14 +08:00
Gadfly 3f6d17aba2 feat: 升级org.jetbrains.intellij.platform 2025-12-16 23:24:11 +08:00
Gadfly 9b6821b5c9 feat: webview版本号跟随build.gradle 2025-12-15 17:35:02 +08:00
zkpaiminmin 8d041bcbac feat: 提交v0.0.3版本 2025-11-23 23:37:28 +08:00