The model list sits above Preset/Effort, so the pointer used to steal the
submenu while crossing those rows. First open stays immediate; switching
waits 200ms and is cancelled if the pointer reaches the already-open fly-out.
Index Codex 0.148+ sessions whose user prompt is a response_item,
and keep provider authJson inline instead of PasswordSafe.
Group DSH CLI install and local host as one product card. Portal
alert dialogs to body so confirm stays clickable, and skip phantom
scrollbars on submenus that already fit.
Merge model, effort, speed, and 1M context into one summary trigger
with fly-out submenus that stay inside the plugin viewport. Compact
mode labels on the toolbar and add a short enter animation.
- Reuse the caller's long-lived CodemossSettingsService instead of
rebuilding the whole manager graph on every webview poll
- Align z.ai cache TTL (115s) with the 120s webview poll cadence so
back-to-back polls dedupe onto one probe
- Extract a ZaiTransport seam and add the tests the original PR body
claimed: Bearer token/URL derivation, TTL enforcement, stale fallback,
API-key fallback, and cache keyed by url+token (account switches no
longer serve the previous account's quota)
- Merge duplicate period windows (TOKENS_LIMIT + CREDIT_LIMIT both
mapping to 5h), keeping the worse usage pct
- Cap stale-cache fallback at 30 minutes and surface the stale flag in
the tooltip as a data-may-be-outdated hint
- Allow plain-HTTP monitor probes only for loopback hosts so Bearer
tokens never travel plaintext to a remote host
- Show the plan tier as the first tooltip line
- keep legacy non-absolute bridge payloads as plain text instead of
silently dropping them
- only absolute-path-looking @ markers disable the manual single-path
fallback, so emails and annotations no longer block it
- share one Gson instance and request browser focus on the EDT in
addFileReferences
JCEF does not route target=_blank anchors to the system browser, so
clicking docs links in the CLI install dialog, MCP help dialog, and
MCP marketplace details did nothing. Intercept the clicks and send
them through the existing openBrowser bridge instead.
- add a DSH preset selector with built-in and user-installed presets\n- persist the selected preset per tab and pass it through the session bridge\n- apply preset compositions to spawned headless DSH hosts with reload support
Extract looksLikePathSegment into webview/src/utils/pathSegment.ts so the
display-side scanner (CollapsibleTextBlock) and the input-side fallback
scanner (useFileTags) share one rule: a word after a space continues the
path when it contains a path separator or ends with a file extension,
with any trailing #L line marker stripped first.
PR #1576 applied this rule only to message display; the chat input box
still truncated absolute paths whose filenames contain spaces (e.g.
"第六章 框架开发实践.md"), and its comment promised extension support the
code did not have. Reuse the shared helper there, sync the comments, and
move the misplaced convertAtFileRefsToLinks docstring back to its
function.
Tests: new pathSegment.test.ts unit tests; useFileTags.test.ts gains
fallback cases for spaced absolute paths with and without line markers.
- Treat transient IO/metadata read failures as pending instead of
terminal error in CodexSubagentHistoryLoader, and fix a latent NPE
for agentId-only status requests
- Gate terminal error on success === true in history merge and subagent
status mapping so later snapshots can correct transient errors
- Validate requestId against the latest sent poll request before merging
status batches
- Show non-Codex (Claude) lookup errors again while keeping Codex
pending noise hidden
- Restore narrow start-of-output error detection for apply_patch results
- Cache Codex session scans for 2s to avoid double full-tree walks
per poll
- Reject ".." segments in agentPath validation
The Claude model mapping (MODEL_ID_TO_MAPPING_KEY / DEFAULT_MODEL_MAP /
MODEL_LABEL_KEYS, fed by the claude model-mapping setting) is keyed by
claude-* ids. Third-party catalogs — agy and the CLI providers — expose
models whose ids collide with those slots (e.g. claude-sonnet-4-6), so
the dropdown relabeled and re-iconed foreign catalog entries with the
user's Claude mapping.
Guard both lookups with currentProvider === 'claude': non-claude
providers now render catalog labels verbatim and resolve icons from the
raw model id.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolve conflicts with the DSH provider that landed on the base branch
after this PR was opened. Both providers now coexist:
- provider registries, CLI detection, and settings list omp + dsh
- mode/model state hooks and persistence handle both provider slices
- ModeSelect keeps the omp role-mode branch; dsh joins the headless
CLI filter branch
- i18n (en/zh/zh-TW) carries both tool entries
Verified: webview vitest 1366/1366, ai-bridge node --test (532 pass,
same 19 pre-existing local-env failures as base), gradle compile +
targeted unit tests, tsc --noEmit.
- drain dsh bridge subprocess stderr so commands no longer pseudo-timeout
(DshHostHandler, DshHistoryReader), with stderr tail in error payloads
- validate dsh host/bin settings before persisting; atomic settings write;
guard start/stop lifecycle re-entry; name bridge reader threads
- split oversized sendMessage/foldHistoryEvents/runDshCommand into focused
helpers (behavior-preserving)
- clear mux-open and bridge-drain race timers so finished turns release the
node process promptly
- best-effort rejected/empty respond when approval or question bridging
fails, so the dsh host never waits for the 15min watchdog
- idle backstop for turns whose own result was skipped as foreign
- grok: count only evidence-backed edits as successful on the error path;
seq-based permission ledger keys; narrow isPermissionMethod to exact ACP
permission methods
- ws-client: cap aggregate fragmented message size and fail on protocol
violations (orphan continuation, data frame mid-fragment)
- tighten dsh host pid-reuse guard to bin path/basename or token match
- opencode models redirect via mkdtemp private directory (CWE-377)
- conversation-chain: always return an array; skip sidechain rows when
backfilling parentUuid
- collect open editor files on the EDT; unify retired-model id trim
- webview: keep useFileChanges memo pure (enrichment moved to an effect with
equality bail-out); 24h TTL for the file touch registry; disable the dsh
auto-start checkbox until the first status arrives
- add 40+ tests covering the new behavior
When the user had previously selected text inside the chat input box and then
triggered an IDE action (Add Selection / Add File to CC GUI), the webview's
stale non-collapsed selection was still anchored in the editable. The caret
insertion path ran range.deleteContents() on that stale range, silently
deleting all the text the user had already typed (#1700).
External content (code snippets, file paths, quote chips) arrives from IDE
actions, never from typing inside the box, so a non-collapsed range is never
a meaningful insertion point. Guard all three Java-interop insertion paths:
- tryInsertExternalSnippetAtCaret (insertCodeSnippetAtCursor)
- insertSingleFilePath (handleFilePathFromJava)
- addQuotedSnippet
Now only a collapsed caret inserts at position; a stale non-collapsed
selection falls back to appending at the end, preserving existing content.
Adds regression tests reproducing the select-all stale-selection scenario
for both snippet and file-path paths.
Closes#1700
Codex CLI v0.149.0 removed the 'untrusted' approval policy - its
ask-before-run semantics were merged into 'on-request'. The plugin
still mapped default/plan/sandbox permission modes to
approval_policy=untrusted, so every message failed with:
Error: approval_policy = "untrusted" is no longer supported;
remove this setting
and Codex became completely unusable after upgrading the CLI
(v0.146.0 -> v0.149.0) (#1702).
- permission-mapper.js: SANDBOX / DEFAULT now map to on-request
- CodexSDKBridge.java: plan / default env override now injects
on-request instead of untrusted
- codex-utils.js: drop 'untrusted' from VALID_APPROVAL_POLICIES so
stale env values are ignored instead of forwarded
- i18n: update codexModes.default.tooltip in all 10 locales
'on-request' is supported by both old and new CLI versions, so this
is safe for all users.
API-key and proxy backends never emit rate_limit_event, so the first
polls answer 'unavailable' — the hook now stays idle (bar hidden)
instead of showing a permanent Usage dash. Once real data arrives the
indicator behaves as before, keeping the last data while re-polling.
Co-Authored-By: Claude <noreply@anthropic.com>
Surfaces Claude subscription rate-limit usage (utilization % + reset) in
the ContextBar using the plan-usage indicator from the previous commit.
- Java: ClaudePlanUsageService caches rate_limit_info from the SDK stream
(utilization→capacity_pct, resetsAt→reset_at, 5h/7d window by reset
delta); TTL-fresh snapshot served to the webview poll.
- Java: ClaudeMessageHandler adds a rate_limit_event case → cache.
- Java: ClaudePlanUsageHandler bridges get_claude_plan_usage polls →
window.updateClaudePlanUsage (registered in ChatWindowDelegate).
- Webview: useClaudePlanUsage poll hook (120s) + ContextBar renders the
indicator for the claude provider.
- ClaudePlanUsageServiceTest: rate_limit_event parsing + cache behavior.
Note: rate_limit_event only fires on real Anthropic (OAuth subscription)
backends; on proxies it never arrives, so the bar stays hidden.
Co-Authored-By: Claude <noreply@anthropic.com>
Adds the provider-agnostic plan-usage UI for the chat input ContextBar:
- planUsagePace.ts: pace coloring (TP = usage %, TT = linear time budget
through the reset window), capacity payload normalization into a
PlanUsageSnapshot, window resolution/switching (5h/7d) with persisted
selection, and reset formatting (short bar label without trailing
period + full tooltip datetime).
- PlanUsageIndicator.tsx: mini bar + % + window chip + short reset +
worst-window dot; tooltip lists all windows and reset times.
- context-bar.css: .plan-usage* styles (green/yellow/red pace colors).
- Unit tests for the pace utils and the indicator.
Co-Authored-By: Claude <noreply@anthropic.com>
- ConfigSelect: add localized Official Docs link opening docs.mossx.ai
- tokentracker-dashboard: portal Base UI overlays into .tt-dashboard
scope so popovers keep scoped preflight/CSS vars/dark variant
- DateRangePopover: add Clear button for selected range
- test: poll for turnSink registration in persistent-query-service test
Keep question and plan-approval cards inset from tool-window edges so JCEF cannot clip their rounded borders. Preserve stretched collapsed layouts when the overlay aligns its children to the end.
claude-sonnet-4-7 was retired from the Anthropic API but remains the
default model hardcoded in both the webview (DEFAULT_CLAUDE_MODEL_ID,
default props) and the Java side (SessionState, HandlerContext,
ChatWindowDelegate, ClaudePricingTable). Every flow that falls back to
the default - or restores a persisted tab that had Sonnet 4.7 selected -
now fails on every send:
There is an issue with the selected model (claude-sonnet-4-7[1m]).
It may not exist or you may not have access to it.
LEGACY_CLAUDE_MODEL_ID_ALIASES also mapped sonnet-4-6 -> sonnet-4-7,
i.e. one retired id to another retired id, so normalizeClaudeModelId()
kept returning a dead id (#1678).
Webview:
- DEFAULT_CLAUDE_MODEL_ID: sonnet-4-7 -> sonnet-5 (same-tier successor)
- legacy aliases now map every retired id to a live model:
sonnet-4-6/sonnet-4-7 -> sonnet-5, opus-4-6 -> opus-4-8
- remove claude-sonnet-4-7 from CLAUDE_MODELS and sonnet47 i18n entries;
move the "Use the default model" description to Sonnet 5 (all locales)
- default selectedModel props use DEFAULT_CLAUDE_MODEL_ID instead of
duplicated literals
Java:
- sync all four defaults to claude-sonnet-5
- SessionState.setModel() migrates retired ids on write so restored
.idea/claudeCodeTabState.xml tabs self-heal instead of spawning a CLI
pinned to a dead model; [1m] suffix is preserved
- lookup-table entries (pricing/context-limit/effort sets) keep the
retired ids so historical usage stats keep resolving
Fixes#1678
Replace per-edit +/− summation with a session ledger (baseline→current
diff), recognize Search Replace style tools, mark multi-agent/cross-tab
touches on the same file, and cover the behavior with unit tests.
The allowShellFileModification switch and policy did not provide reliable
pre-execution blocking for Codex (and only partial coverage elsewhere), so
remove the setting, UI, env, and Claude/Codex/Grok interception paths.
Root causes for blank history until switch-away-and-back:
1) historyLoadComplete fired before StreamMessageCoalescer flushed
updateMessages, releasing the transition guard with an empty stash.
2) clearMessages wiped a post-barrier stashed snapshot when IPC reordered.
3) Same-session Grok reopen began a transition (cleared UI) while the
backend soft-reloaded without historyLoadComplete.
Flush the coalescer before historyLoadComplete, preserve post-barrier
deferred snapshots, soft-reload non-Codex same sessions without wiping,
and always complete soft reloads with historyLoadComplete.
History loads that finished while __sessionTransitioning was true used to
be dropped permanently because historyLoadComplete never re-applied them.
Stash the latest snapshot during the guard and flush it when the
transition is released (historyLoadComplete / setSessionId / timeout).
Add allowShellFileModification (default off) so file changes go through
Edit/Write for StatusPanel stats. Deny Bash-like tools that look like
they mutate files; when the setting is on, allow them with a no-stats
warning in the permission dialog.
detectSlashTrigger and detectHashTrigger only fired when the trigger
character was at the absolute line start. Typing content first made / and
# unreachable without clearing the input or inserting a newline.
Allow the trigger when preceded by visible whitespace (space, tab, etc.)
so users can type content, press space, then type / or # — matching the
existing ! and $ triggers and the CLI. Zero-width invisible characters
(ZWSP/ZWNJ/BOM) are still treated transparently by isLineStart and are
NOT counted as a separating space, so 'a<zwsp>/rev' still does not
trigger.
Fixes#1661