Commit Graph
2305 Commits
Author SHA1 Message Date
zhukunpenglinyutong d84d676e26 fix: make the Node child timeout a real deadline for input history and session queries
InputHistoryHandler.executeNodeScript and ClaudeSessionQueryService
.runSessionQuery still read stdout to EOF before calling waitFor(30s),
so a child that hung with stdout open blocked the caller forever.
InputHistoryHandler also wrote stdin synchronously before the timer
started, which blocked forever once the payload outgrew the pipe buffer
of a child that never read it.

Extract the #1778 pattern into bridge/NodeProcessRunner and use it from
NodeJsServiceCaller, InputHistoryHandler and ClaudeSessionQueryService:
- stdout is drained and stdin written on named daemon threads, so
  waitFor(timeout) is the only blocking step and also covers stdin;
- on timeout the child is terminated and a TimeoutException is thrown;
- the output is only used once the reader reached EOF: if stdout is
  still open 2s after exit, or the reader failed, the call fails instead
  of returning possibly truncated output (the #1778 code joined the
  reader without checking isAlive);
- the child is registered with ProcessManager and unregistered in
  finally, as before.

ClaudeSessionQueryService now has its 30s deadline cover the whole run,
including streaming the output.
2026-10-26 21:04:38 -07:00
朱昆鹏 9e624f729c Merge pull request #1778 from yibeiqingke/perf/fix-nodejs-service-timeout
fix(history): make the node-service timeout actually reachable
2026-10-27 11:27:28 +08:00
朱昆鹏 d34b014455 Merge pull request #1776 from yibeiqingke/perf/session-node-probe-off-edt
perf(session): move node version probe off the JCEF UI thread
2026-10-27 11:26:45 +08:00
朱昆鹏 16b1f9780e Merge pull request #1937 from EeeasyCode/feat/claude-version-too-old-update
feat(claude): offer an in-place SDK update when Claude Code is too old for the model
2026-10-27 11:16:03 +08:00
zhukunpenglinyutong f50dd04d8b fix(claude): reload the SDK in every chat window without cutting replies short
Follow-up to the review of the in-place Claude SDK update:

- Replace the shutdown of the current window's daemon with a shared SDK
  generation. Once the SDK changes, every Claude daemon in the IDE restarts
  before its next request, and a daemon serving a request is left alone, so
  an update from the Dependencies page no longer aborts a reply with
  "Daemon stopped".
- Run installs of the same SDK one after another, so the chat button and
  the Dependencies page cannot run npm into the same directory at once.
- Report a run where every npm attempt timed out as a failure instead of
  falling through to success.
- Add the previously installed version and the Claude CLI override to the
  install result. The card says when the update left the newest supported
  SDK in place, or when the custom CLI is what needs updating.
- Keep the update state in a shared store, so a card that remounts still
  shows the running update and its result. The same error shown after the
  update gets the button again.
- Show npm's latest output while updating, give up after 15 minutes so a
  lost reply cannot block retries, and explain failures that come without
  a reason.
2026-10-26 20:13:36 -07:00
朱昆鹏 4671827652 Merge pull request #1953 from mvanhorn/fix/1912-android-studio-jcef-startup
fix(claudecodegui): show JCEF installation guidance before chat window construction
2026-10-27 10:43:06 +08:00
zhukunpenglinyutong 493e3fd7e7 fix(jcef): tailor missing-JCEF guidance and surface it from actions
- Use the Android Studio plugin text only for Android Studio 2026.2+ on
  Windows/macOS; other IDEs get new IDE-neutral module text instead of
  Boot Runtime advice, which cannot restore missing platform classes.
  JBCefBrowserFactory now shares the same Android Studio predicate.
- Quick Fix and New Tab show a sticky balloon with the steps instead of
  a status-bar tooltip; Quick Fix checks before its prompt popup.
- Say "install, enable, or update" Web Browser (JCEF) in all locales.
- Test that guarded entry points link with the JCEF module hidden, that
  the same setup reproduces the #1912 link failure, and that every
  locale defines the guidance keys.
2026-10-26 19:36:27 -07:00
zhukunpenglinyutong 5695ee3932 fix(codex): reopen approval dialogs whose answer never reached Codex
Dialogs close as soon as the page hands an answer to Java. When Java
could not deliver it, the failure ack reached the page but nothing
handled it, so Codex kept waiting on a request the user could no longer
see and the turn looked stuck until it was stopped.

- Track each Codex answer the page sends; on a failure ack show a toast
  and reopen the dialog once. Skip the reopen when Java marks the
  failure as not retryable, the deadline has passed, it was already
  retried, or the runtime closed the dialog in the meantime.
- Give control-command timeouts a readable error. A null message became
  JsonNull, which Gson drops, so timeouts read as success on the page.
- Mark unknown or stale interactions as retryable: false.
- Log undelivered interaction responses in the IDE log.
- Route the nine Codex send sites through two shared helpers.
2026-10-26 19:35:58 -07:00
zhukunpenglinyutong e27bf14fc8 fix(codex): stop duplicating rule buttons in command approvals
When the app-server advertises availableDecisions, that list already
carries the exec-policy amendment it will accept. The webview appended
proposedExecpolicyAmendment on top, so the dialog showed two identical
"allow with this command rule" buttons. Use the advertised list as-is
and only synthesize amendments when the server sends no list.

Rule buttons now show the command prefix or host they would allow,
truncated with the full text on hover.
2026-10-26 19:35:58 -07:00
朱昆鹏 96e71745a2 Merge pull request #1976 from hebulin/fix/session-page-cursor-parser
refactor(bridge): extract turn-cursor parsing into a tested helper
2026-10-27 10:25:54 +08:00
zhukunpenglinyutong 0c37707ea4 fix(bridge): keep oversized turn cursors on the cursorReset path
parseOptionalTurnCursor rejected integers above Number.MAX_SAFE_INTEGER, so
a cursor like 1e21 came back as the latest page with cursorReset=false while
6 or 1000 against a five-turn history still came back with cursorReset=true.
The 2^53 line is not a meaningful boundary: only
buildSessionMessagesPagePayload knows the history length, and comparing 1e21
against it is exact.

The flag also matters to the only caller that sends a cursor.
SessionMessageOrchestrator.loadEarlierClaudeHistoryPage replaces its
transcript when cursorReset is set and prepends the page otherwise, so a
latest page returned without the flag would duplicate every visible message.
The Java cursor is a 32-bit int, so this cannot occur from the plugin today,
but the parser should not encode the opposite rule.

Use Number.isInteger again, document why the upper bound is left to the
payload builder, and replace the safe-range tests with ones asserting
cursorReset for any cursor beyond the history. Also drop the redundant
empty/undefined guard on args[2]; the parser already treats both as absent.
2026-10-26 19:19:12 -07:00
朱昆鹏 054d018b26 Merge pull request #1972 from GGMGG/fix-sdk-version-query-v063
fix(dependencies): bound SDK version queries and expose lookup failures
2026-10-27 09:34:27 +08:00
zhukunpenglinyutong d5a73589c5 fix(dependencies): use an existing locale key for the version retry button
common.retry is not defined in any locale, so the button rendered the raw
key. Switch to settings.cli.retry and assert the lookup-failure keys exist
in the shipped en/zh locales, since the i18n mock echoes unknown keys.
2026-10-26 18:34:01 -07:00
Jefung 1e1fa18bb9 fix(webview): restore lost bridges when reactivating remote chat tabs (#1967)
Remote JCEF can replace a hidden chat page without delivering onLoadEnd.
Java still reports frontendReady for the old document, so onTabActivated
skipped recovery and the new page waited forever for sendToJava, leaving
the tab on "Checking SDK status...".

Tab activation now runs the existing idempotent bootstrap for the current
browser and page generation before scheduling retries. Disposed, inactive
and mismatched pages are still skipped, and ready pages start no retries.

A frontend_ready that arrives while Java still holds the ready flag can
only come from such a replaced page, which booted from the tab's original
HTML snapshot. Treat it as runtime recovery so Java pushes the current
provider, model and reasoning state before replaying the transcript.
2026-10-27 09:28:00 +08:00
hebulin f144a6ac06 refactor(bridge): extract turn-cursor parsing and reject unsafe integers
getSessionPage parsed the optional beforeTurn cursor inline and accepted any
integer-valued number. Values outside the safe integer range (1e21, 2^53 and
above, or their string forms) pass Number.isInteger, reach
buildSessionMessagesPagePayload and are read there as a cursor beyond the
history length, so the response carries cursorReset=true: the client discards
its cached history and reloads from scratch for a value that was never a usable
cursor.

parseOptionalTurnCursor() now owns the parsing and applies
Number.isSafeInteger, so those values degrade to the latest page like every
other unusable cursor. Absent cursors (null, undefined, '', whitespace) still
return null, and an explicit 0 is still preserved as "the page before the first
turn". limit is untouched: its guard is "> 0", so a polluted 0 already falls
back to 30.

This builds on #1867 (2dc9ecd5), which fixed the empty-cursor coercion, and
carries over the follow-up work requested when #1868 was closed as superseded:
the extracted pure function, the safe-integer tightening and unit tests. Adds
ai-bridge/channels/claude-channel.test.js covering absent, explicit-zero,
numeric, unusable and unsafe-integer inputs, plus the cursorReset contrast at
the payload layer. No behavior changes for valid cursors.
2026-10-27 09:07:07 +08:00
Gadfly ea4fd9bbff feat(codex): carry editor context beside the user's words, not inside them
Changing editor state used to be pasted straight into the message text,
spending the user message's native budget and polluting history replay.
Each turn now freezes structured additionalContext fragments instead
(ide_context, open_tabs, workspace_context, referenced_files_<index>,
terminal_context_<index>), so every fragment enjoys its own native budget
and the request text stays pristine.

The service sniffs the selected CLI once per child process via
app-server generate-json-schema --experimental to learn whether
turn/start accepts additionalContext, and re-sniffs after a runtime
replacement; discovery never creates a thread or turn and cancels leave
it early. Older CLIs get the official desktop text envelope with UTF-8
text-element byte ranges shifted accordingly, and history replay strips
that envelope so users only ever see their own request.

Cover the flow with schema-probe, fallback, cancellation and daemon
tests on the bridge side plus context-budget, payload-copy and display
sanitizer tests on the Java side; document the contract in
docs/codex/app-server.md.
2026-10-25 21:37:23 -07:00
Gadfly e78a9ca897 fix(codex): preserve streamed messages and replay tool batches consistently
Codex streaming could omit commentary, reasoning, and edit cards between
batches until the conversation was reloaded. Historical exec wrappers also
collapsed supported parallel calls into generic exec cards and used command
labels that differed from live rendering.

Preserve snapshot ordering and complete message corrections:
- Compare complete raw message content when selecting the transported suffix;
  keep structural signatures limited to snapshot scheduling.
- Apply a buffered full snapshot before its dependent tail update advances
  the sequence barrier, retaining intermediate items during React batching
  and stream completion.

Restore recorded tool batches without guessing result ownership:
- Associate Promise.all and Promise.allSettled results with their original
  array slots, including independently printed index labels in forEach and
  bounded for loops.
- Retain labeled arrays, primitives, plain text, and label-like values.
- Restore mixed command and write_stdin batches while keeping polling tied
  to the original process card.
- Match identical commands through confirmed process identities or unique
  explicit absolute working directories, including file URIs and Windows
  paths, while preserving literal POSIX backslashes.
- Never assign unindexed parallel process receipts by arrival order; retain
  the original wrapper whenever ownership cannot be established.

Keep local Promise computations out of the visible tool timeline:
- Preserve Promise.resolve expressions and indexed results as internal data
  without executing historical source.
- Filter these entries through the shared rendering predicate so they neither
  create cards nor interrupt command groups in live or historical messages.
- Separate rejection metadata from result fields, distinguish Promise.all
  values from settled envelopes, and decode nested local receipts only when
  the source proves that the complete settled receipt was printed.
- Keep flattened local Promise.all output in its original wrapper rather
  than interpreting data fields named status or error as execution outcomes.

Align historical command rows with live presentation:
- Preserve recorded summaries, approval reasons, and parsed command actions.
- Accept both list_files and listFiles directory action names.
- Remove generated English command summaries and retain Bash tool identities
  for legacy reads and searches so the shared renderer controls row labels.

Extend Java, React, and browser regression coverage for snapshot ordering,
process ownership, mixed batches, local result preservation, command labels,
and continuous tool grouping. Update the Codex runtime documentation and
browser fixtures to describe the resulting behavior.

Validation:
- 199 Java tests passed across CodexKnownExecReplayTest,
  HistoryMessageInjectorTest, CodexHistoryPageIndexTest, and
  StreamMessageCoalescerStreamEndHookTest.
- Gradle checkstyleMain passed.
- 67 targeted frontend tests passed across snapshot callbacks, MessageItem,
  GenericToolBlock, tool constants, and command presentation.
- TypeScript test-project checking and git diff --check passed.
2026-10-25 21:37:23 -07:00
zhukunpenglinyutong b767338053 fix: 按审查建议修复 (#1953) 2026-10-25 14:27:00 +08:00
hebulin 76c302520c fix(settings): stop stripping user-configured API_TIMEOUT_MS on provider sync (#1729)
ClaudeSettingsSyncPlan.CLAUDE_MANAGED_ENV_KEYS listed API_TIMEOUT_MS as a
plugin-managed key, so every provider sync deleted any user-configured
value from ~/.claude/settings.json. Users running slow local backends
(Ollama with 80k+ token contexts) had no way to extend the request
timeout - the CLI's built-in default cut the connection mid-generation
and the local server aborted the task (#1307).

API_TIMEOUT_MS is a performance knob, not a credential: the plugin does
not set it, does not need to own it, and clearing it serves no isolation
purpose. Remove it from the managed set so a user-configured value
survives provider syncs; when unset, the Claude CLI keeps its own
default.

Closes #1307
2026-10-25 14:21:25 +08:00
GGMGG a24da0b851 fix(jcef): fence browser startup recreation and resource disposal (#1971) 2026-10-25 14:18:03 +08:00
zhouxiangsuper-create a347f5fd63 Feature/claudecode provider noop config write (#1969)
* Fix handling of empty currentId in ProviderManager

Allow explicitly empty currentId to be a valid disabled state without triggering a config rewrite.

* Create ProviderManagerNormalizationTest.java

* Add files via upload

* Delete unused file
2026-10-25 12:17:14 +08:00
GGMGG 4a09d33a16 fix(dependencies): bound npm queries and expose version lookup failures 2026-10-24 17:52:25 +08:00
朱昆鹏 e090a4491f Merge pull request #1964 from zhukunpenglinyutong/feature/v0.6.2
docs(changelog): add v0.6.2 release notes
2026-10-21 23:14:48 +08:00
朱昆鹏 42283aaa3f Merge pull request #1963 from zhukunpenglinyutong/feature/v0.6.2
Feature/v0.6.2
v0.6.2
2026-10-21 23:11:42 +08:00
zhukunpenglinyutong 04f5dbcde0 docs(changelog): add v0.6.2 release notes
Cover the 19 commits merged by PR #1963:

- feat: persist the chat font-size level in ~/.codemoss/config.json so the
  chosen scale survives IDE restarts, acknowledged by request ID
- perf: fetch the compressed entry and stylesheets in parallel and reuse
  verified (SHA-256) startup assets across chat tabs
- fix: Token Tracker dashboard crashed with removeChild because the entry
  was evaluated as a blob while lazy chunks resolved the canonical URL;
  an import map keeps a single entry/React instance (#1951)
- fix: keep #L..-L.. visible on long file references in input file tags
- fix: scan plugin skills declared as individual directories (#1961)
- fix: keep the $ Codex skill list on partial skills/list errors
- fix: let Claude subagents keep their own permission mode
- fix: keep pasted image drafts in sessionStorage so tabs cannot share them
- fix: keep dropdown fly-outs anchored at any font zoom
- build: Aliyun Maven mirror first and foojay JDK toolchain resolution

webview/src/version/changelog.ts is regenerated by
webview/scripts/extract-changelog.mjs, not edited by hand.
2026-10-21 22:50:58 +08:00
zhukunpenglinyutong 1730386957 test(webview): assert blob+importmap entry bootstrap in HtmlLoaderTest
PR #1955 让入口以 import("https://cc-gui-webview.local/assets/xxx.js")
的方式加载,Java 测试随之断言该写法;随后 PR #1962 为支持压缩资源缓存、
SHA-256 校验和入口模块单实例,把启动引导改回 blob + importmap,但只改了
webview/ 下的文件,导致 HtmlLoaderTest 在 Linux Java 单元测试中失败。

同步断言到当前设计(与 webview/scripts/copy-dist.test.mjs 一致):
- 入口以单个 .js.gz canonical 地址拉取
- importmap 把 canonical 模块地址映射到已校验的 blob
- 只通过 await import(objectUrl) 求值一次
- 反向断言禁止直接 canonical import 和 <script type="module">,
  避免入口被求值两次、出现两份模块实例

修复 Tests / Java unit tests (Linux) 失败。
2026-10-21 22:43:52 +08:00
朱昆鹏 e2dcbf1de5 Merge pull request #1962 from Jefung/codex/perf-webview-startup-cache
perf(webview): reuse verified startup assets across remote chat tabs
2026-10-21 22:33:13 +08:00
zhukunpenglinyutong 3be98c0a85 Merge branch 'feature/v0.6.2' into codex/perf-webview-startup-cache
Resolve semantic conflict with e0c356a5 (preserve entry module identity):
keep the verified startup-asset cache and add an import map that remaps the
canonical entry URL to the evaluated blob, so lazy chunks importing the
entry keep a single module identity while cached bytes are still reused.
2026-10-21 22:31:48 +08:00
朱昆鹏 6a1e6587d2 Merge pull request #1957 from elexiang/codex/fix-selection-reference-lines
fix(input): keep selection line ranges visible in file tags
2026-10-21 22:23:04 +08:00
朱昆鹏 591cbe9076 Merge pull request #1955 from elexiang/codex/fix-1951-usage-module
fix(webview): preserve entry module identity for usage dashboard
2026-10-21 22:16:19 +08:00
朱昆鹏 53bdea25d9 Merge pull request #1961 from JackLin513/fix/plugin-skills-declared-as-dirs
fix(skills): scan plugin skills declared as individual directories
2026-10-21 22:13:38 +08:00
zhukunpenglinyutong 297259efb9 fix(skills): also scan child dirs when the declared path is itself a skill
When a directory both parses as a skill (root SKILL.md) and contains
child skill directories, scanning only the root silently dropped the
child skills. Scan both: asset folders contain no SKILL.md and are
skipped by parse, so single-skill and parent-directory manifests keep
working unchanged while mixed layouts now yield every skill.

Adds a regression test for the mixed shape.
2026-10-21 22:12:15 +08:00
zhukunpenglinyutong 7a5ae7c905 chore(build): bump to 0.6.2 and make dependency resolution resilient in CN
Direct connections to repo.maven.apache.org are frequently TLS-reset
behind the GFW, so the Aliyun public mirror is consulted before
mavenCentral. The foojay toolchain resolver plugin lets Gradle download
the required JDK toolchain instead of failing when the local JDK does
not match the target version.
2026-10-21 22:00:27 +08:00
Gadfly 5a54320020 fix(ui): keep dropdown fly-outs anchored and inside the viewport at any font zoom
Submenu geometry mixed zoomed getBoundingClientRect values with
layout-pixel scroll sizes, so above 100% font zoom the effort fly-out
drifted off its row and overflowed small viewports. Compute the whole
submenu layout in layout pixels and measure the natural content size
even when maxHeight clips the box.

The main dropdown now clamps its width to the viewport and matches
the CSS min-width floor, and open menus follow window resizes and
content changes through a ResizeObserver instead of measuring once
at open time.
2026-10-21 21:21:17 +08:00
Gadfly 0f0341e261 fix(ui): keep pasted image drafts inside each webview's own session
localStorage drafts are shared by every same-origin chat tab, so one
webview's screenshots could be restored by another. Persist the draft
in sessionStorage instead: it still survives input remounts and page
reloads but never crosses webviews, and the legacy shared draft is
deliberately left behind because its owner is unknown.

When a save fails or exceeds the size cap, drop the previous draft so
removed images stay removed after a reload, and skip rewriting a
just-restored draft so full storage cannot wipe what was restored.
2026-10-21 21:21:17 +08:00
Gadfly d81daf87b1 feat(ui): remember the chat font-size level across IDE restarts
JCEF pages loaded via loadHTML cannot rely on localStorage surviving a
restart, so the chosen scale vanished every time the IDE reopened. The
level now lives in ~/.codemoss/config.json next to the font-family
preference and rides the existing resolved UI-font payload.

Explicit selections send set_font_size_level with a request ID and are
acknowledged through the resolved font config; a shared external store
keeps Settings, the global --font-scale and the OSR repaint nudge in
sync, browser storage stays an immediate cache only, an unreadable
config file is rejected instead of replaced, and a legacy browser choice
is migrated without pinning the default.
2026-10-21 21:21:17 +08:00
Gadfly a457ee3429 fix(claude): let subagents keep their own permission mode instead of the parent's
The PreToolUse hook read the parent's cached mode for every call, so a
worker running under the native auto reviewer got forced to "ask" as soon
as the parent switched modes, and a worker's EnterPlanMode/ExitPlanMode
mutated the parent Query or opened a parent plan-approval dialog.

Recognized permission_mode values from the hook input now win over the
parent state for worker calls; worker plan transitions, plan-file
ownership and the SDK-only dontAsk/bubble modes yield to the native
permission flow, and missing or unknown modes still fall back to the
parent policy.
2026-10-21 21:21:17 +08:00
czf 250e9f4a2f perf(webview): 并行加载并缓存远程聊天启动资源 2026-10-21 20:36:00 +08:00
jacklin 2df4807ad7 fix(skills): reuse parsed metadata and clean up test temp dirs
Addresses review feedback on #1961:
- reuse the already-parsed metadata when the scanned directory is itself a
  skill, instead of parsing SKILL.md a second time
- use JUnit's TemporaryFolder rule so test directories are deleted after each
  test instead of accumulating in the system temp dir
2026-10-21 20:22:16 +08:00
jacklin eaf869c977 fix(skills): scan plugin skills declared as individual directories
`scanSkillsAsCommands` treats the path it receives as a parent directory and
scans its subdirectories for SKILL.md. But `plugin.json` may declare `skills`
as an array of individual skill directories:

  "skills": ["./skills/engineering/ask-matt", "./skills/engineering/tdd"]

The plugin reference allows both forms - "each a directory of <name>/SKILL.md
folders or one folder holding SKILL.md directly". With the per-skill form,
every listed directory is passed through as-is, nothing parses as a skill, and
all of the plugin's skills silently yield zero slash commands - no log line,
no warning.

Repro: enable a plugin that declares individual skill directories (for
example mattpocock-skills, 21 skills). The log reports
"Slash commands resolved locally: 15 commands" and none of that plugin's
skills appear in the "/" menu.

Fix: if the given directory itself contains SKILL.md, scan it as a single
skill instead of looking for subdirectories.

Tests: SkillDirScanTest covers the per-skill manifest shape, the parent
directory shape (regression guard) and a directory with no skill.
`declaredSkillDirectoryItselfIsScanned` fails without the change.
2026-10-21 20:02:10 +08:00
he_dai_xiang 47a594a1ef fix(input): keep selection line ranges visible in file tags 2026-10-21 11:16:09 +08:00
he_dai_xiang 6128a8e373 test(webview): align HTML bootstrap assertion with canonical entry import 2026-10-21 10:19:25 +08:00
he_dai_xiang e0c356a542 fix(webview): preserve entry module identity for usage dashboard 2026-10-21 10:08:30 +08:00
Matt Van Horn e3c66a4a5a fix(claudecodegui): show JCEF installation guidance before chat window construction
The tool-window entry point now checks that JBCefBrowser and
JBCefOSRHandlerFactory can load through the plugin class loader without
running their static initializers. Missing classes or linkage errors
show a Swing panel with existing JCEF installation and restart guidance,
then return before bridge startup, tab restoration, or listener
registration. Added tests cover availability, missing classes, linkage
failures, static initialization, and factory loading with JCEF hidden.

Fixes #1912
2026-10-20 04:18:04 -07:00
zhukunpenglinyutong ef2c5648ef fix(codex): keep Codex skills when the native catalog reports errors
A partial `skills/list` failure (one unreadable SKILL.md, an invalid
frontmatter entry, a stale skill under another cwd) sets the catalog error
while still returning the valid skills. The `$` completion coordinator
treated any error as fatal and published an empty list, which erased every
Codex skill the user had (custom skills included) and marked the native
catalog authoritative, so the backend-scanned `$` list was ignored for the
rest of the session. The picker then reported "no results" with no way back.

Publish whatever the runtime did return on partial errors, and skip the
publish only when the read failed without any rows: a failed read is not an
authoritative empty inventory, so the backend-scanned fallback stays usable
until the runtime answers with real data. `nativeSkills.error` still reaches
the Skills settings warning.

Covered by two coordinator tests: partial error keeps native skills, and an
outright failure no longer swallows the backend-scanned `$` payload.
2026-10-20 11:37:09 +08:00
朱昆鹏 b0463cff60 Merge pull request #1950 from zhukunpenglinyutong/feature/v0.6.1
Feature/v0.6.1
v0.6.1
2026-10-19 20:55:29 +08:00
zhukunpenglinyutong 3816bc6fb7 chore(release): bump version to 0.6.1 and add changelog entries 2026-10-19 20:52:40 +08:00
zhukunpenglinyutong f836375305 fix(codex): keep the permission mode and the effective sandbox in sync
Full Auto could run sandboxed while the selector still read Full Auto. The
permission mode is app-level state that survives a reinstall, but the access
scope only lived in webview localStorage, so a wiped snapshot or a
pre-native-scope migration left the app-server on workspace-write and denied
writes outside the project — with no way to see why. The permissions panel made
it worse: it reported the legacy .idea record as both "desired" and "effective",
so it claimed full access while the runtime was sandboxed, and changing it there
was overwritten by the next message.

- Derive the access scope from the authoritative mode whenever no explicit
  choice is recorded ('default' source), so a reinstall self-heals; an explicit
  'user'/'native'/'migrated' scope is never overridden.
- Honour a persisted sandbox in the snapshot migration and stop treating the
  never-written `codexFullAccessExplicit` flag as the only Full Auto evidence;
  pair a persisted full-access preset with danger-full-access.
- Drive the permissions panel from the chat state (the value every turn sends)
  and write panel changes back into it; show "effective" only from the
  app-server's thread/settings/updated echo, never the requested value.
- Stop reporting fabricated sandboxDesired/sandboxEffective/sandboxConflict
  from ProjectConfigHandler, and drop the matching webview branches.
- Export buildTurnSettings and pin the mode -> approval/sandbox contract with
  tests, since the webview mirrors that mapping.
- Delete codex-sandbox-resolution.js and utils/permission-mapper.js: both were
  unreferenced by production code, and the latter encoded a platform-dependent
  Full Auto mapping that no longer exists.

Tests: webview 2440 passed (tsc clean), ProjectConfigHandler/CodexInteraction
handler tests, 32 persistent-codex-service tests.
2026-10-19 19:38:48 +08:00
이창민 60bbc2c8bb feat(claude): offer an in-place SDK update when Claude Code is too old for the model
The API rejects requests from a Claude Code older than a model's minimum
version ("Claude Code X does not support this model; version Y or newer is
required", error_code claude_code_version_too_old). The plugin runs the
Claude Code bundled in its own SDK, which updating the plugin or the
terminal CLI does not change, so the hint in the message does not help.

- Match the error in the diagnostic card and add an "Update SDK" button
  that sends the existing update_dependency request and shows the result
  in place.
- Restart the Claude daemon after a successful Claude SDK install or
  update. The daemon caches the SDK module it imported, so the next
  message would otherwise keep running the old SDK until the IDE restarts.
2026-10-19 12:55:05 +09:00
朱昆鹏 4e9b0e8ac4 Merge pull request #1945 from 8p98h2fgnd-max/feature/v0.6.0-bug-subagent
fix(ai-bridge): 全量同步模型档位环境变量,堵住子智能体回退到内置模型名
2026-10-18 21:58:34 +08:00