Skip to content

[pull] main from xintaofei:main#160

Merged
pull[bot] merged 9 commits into
MoozLee:mainfrom
xintaofei:main
Jul 25, 2026
Merged

[pull] main from xintaofei:main#160
pull[bot] merged 9 commits into
MoozLee:mainfrom
xintaofei:main

Conversation

@pull

@pull pull Bot commented Jul 25, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

… cards

codex-acp forwards every MCP tool call's outcome to the ACP wire as
`rawOutput = { result: <CallToolResult>, error: <string|null> }`, one layer
above the shapes the delegation parsers read. Nothing peeled it, so with Codex
as the main agent a `get_delegation_status` poll resolved to no report at all:
a batch of tasks collapsed into a single anonymous row that rendered the raw
envelope JSON as its result, carried no task id or duration, and fell back to
the tool-call lifecycle for its badge -- reporting "done" for tasks that were
still running. Codex's persisted rollout carries the bare `Wall time:.../
Output:` wrapper instead, which already parsed, so only the live path was
affected.

Add `peelMcpResultEnvelope`, which strips that envelope plus the `{Ok}` serde
variant Codex writes into its rollout, and run it in `delegation-status.ts`
(both the single-report and batch paths) and `delegation-card.ts`
(`parseToolOutput` and `parseDelegateTaskId`, where the same envelope hid a
running ack's child conversation id). An envelope whose call failed outright
now surfaces its own error string instead of the raw JSON.

The peel is positively identified on both ends so a child agent's arbitrary
output is never mistaken for a companion result: a wrapper key is only followed
when the value under it is a real CallToolResult (carries `content` or
`structuredContent`), and the host error string is only read from
`{result: null, error: "..."}`. A payload that merely owns a `result` or
`error` field of its own is left exactly as it was.

Parsing happens at render time, so existing transcripts pick this up on reopen.
- `temp_roots` pushed the shared unix temp dirs from inside a `#[cfg(unix)]`
  block, leaving the `mut` binding unused on Windows, where `-D warnings`
  turns that into a compile error. The pushes now sit behind `if cfg!(unix)`;
  the resolved roots are unchanged on every platform.
- The policy tests built their fixtures from unix path literals such as
  `/tmp/codeg-xdg`. Those carry a root but no drive prefix, so they are
  relative on Windows and the module's fail-closed guards correctly dropped
  them, leaving the assertions with an empty root list. Fixtures now come
  from a platform-prefixed helper, with the environment value and the
  expected root derived from the same call.
- The assertions that a padded value never widens to the filesystem root
  could not fail on Windows, since `/` is never produced there. They now use
  the platform's own root, and the write-gate check compares against the
  canonical form so the verbatim `\\?\C:\` that Windows canonicalizes to is
  still caught.
An expanded commit in the aux panel's Commits tab rendered its message in full,
so a long release message pushed the file tree and containing branches far off
the bottom of the panel. The body is now capped at 12rem with a bottom fade and
a Show more / Show less toggle that appears only once the text is actually
clipped, matching how a chat user message behaves.

The clamp-and-measure plumbing behind those user messages moves into a shared
useCollapsibleOverflow hook that both call sites use, and the fade class it
applies is renamed collapsed-user-message-fade -> collapsed-content-fade to
match. Show more / Show less are added under Folder.gitLogTab in all ten
locales, reusing each locale's existing chat wording.
…l holds

Opening a file while a diff was on screen raised an uncaught "TextModel got
disposed before DiffEditorWidget model got reset". Monaco's diff widget
watches the model pair it holds and reports the disposal of either one as a
bug, which its default handler rethrows from a timeout, while
@monaco-editor/react tears the editor down in exactly that order: both text
models first, the widget last. Every unmount of the side-by-side viewer hit
it — switching from a diff tab to a file, closing such a tab, and closing the
commit, push, or stash panels.

The viewer now performs the teardown itself, from a layout cleanup that is
guaranteed to run before the library's passive one. It detaches the pair,
which drops the widget's disposal listeners, and only then disposes the two
models, which are anonymous and owned by nothing else; the library is left
with a null model and disposes the widget alone. A test pins that ordering
against a fake that reproduces both the library's teardown and Monaco's
guard.

The deferred first diff read is now cancelled on unmount so it can never
reach a disposed widget, and the editor options sit behind a memo instead of
being re-pushed on every render.
…page

codex-acp attaches an approval policy and sandbox policy to each turn it
starts itself, taken from the collaboration mode picked in the composer. But
`/goal`, `/review`, and `/compact` only send their request and then wait --
codex creates that turn server-side, so it never sees those per-turn values
and falls back to the thread defaults in `~/.codex/config.toml`. Picking
"Agent (full access)" therefore had no effect on `/goal`, which kept running
under `on-request` + `workspace-write` with no network, while every ordinary
turn in the same session ran unrestricted.

Add a "Sandbox & approval" group to the Codex settings card that writes those
thread defaults: the approval policy (untrusted / on-request / never, plus
granular with its five switches), the sandbox mode (read-only /
workspace-write / danger-full-access), and the whole
`[sandbox_workspace_write]` table -- writable roots, network access, and the
two temp-directory exclusions. The backend reads the file with `toml` and
merges with `toml_edit`, so comments and formatting survive, matching how Grok
and Cursor already handle their native config.

The structured payload is a per-field patch rather than a snapshot of the
group. The panel always submits the raw `config.toml` text alongside it and
the structured half is applied last, so a snapshot would push stale control
values over sandbox keys the user had just hand-edited in the raw editor. Only
fields the user actually moved are sent; anything absent is left exactly as it
sits on disk. `approval_policy` and its granular table travel as one unit,
since upstream models them as a single externally-tagged key.

Three guards come from reading the codex source and probing a live
`app-server`. Relative entries in `writable_roots` are rejected on both ends:
codex does not error on them, it resolves them against `CODEX_HOME`, so
`rel/dir` would silently grant `~/.codex/rel/dir` instead of a project path.
When the config defines `default_permissions` the sandbox controls are
disabled and labeled, because it shadows `sandbox_mode` completely. Granular
always writes all five booleans, as three of them have no serde default and
codex refuses to load a config that omits them.

All three settings fold into the config fingerprint, so codex sessions that
are already running are flagged as needing a restart once they change.
…ders

The file tab strip lost its bottom hairline to the right of the tab whenever a
title was long enough to overflow the tab's fixed width — diff tabs in
practice. The strip's Reorder.Group was auto-width, and WebKit sizes such a
container from its items' content rather than their flex-basis, so the group
claimed tens of pixels more than its tabs; that leftover strip belongs to the
group, which carries no ws-strip-line, and the line broke there. The group now
sizes by flex and keeps the trailing drag spacer and maximize button as its own
last child, so every leftover pixel sits in a box that draws the line, and that
wrapper insets its baseline when the last tab is active — the structure the
conversation strip already used.

Maximizing the file column also left the panel resize handle on screen. The
maximized column is an overlay that goes translucent under a workspace
background image, so the handle's hairline showed straight through it, running
down the tab strip and on through the editor canvas below. It is now disabled
and hidden while maximized, keeping its 1px width so the conversation panel is
never resized and its stick-to-bottom scroll never resets.

The side-by-side diff had no real divider between its panes: Monaco leaves
diffEditor.border unset, leaving the split marked only by the blurred 6px
scrollbar shadow it paints on both inner edges. The editor themes now name that
border for light and dark, and the shadows are dropped, so the seam reads as a
crisp hairline.
- feat(codex): **Sandbox and approval policy, from the settings page.** The Codex settings card gains a "Sandbox & approval" group: the approval policy (untrusted / on-request / never, or granular with its five switches), the sandbox mode (read-only / workspace-write / full access), and the workspace-write details — writable roots, network access, and the two temp-directory exclusions. These are the thread defaults that `/goal`, `/review`, and `/compact` actually run under, which the composer's collaboration mode never reached: a goal could stay locked down while every ordinary turn in the same session ran unrestricted. Your changes merge into `~/.codex/config.toml` with comments and formatting intact, and running Codex sessions are flagged for restart once they change.
- feat(git-log): **Long commit messages stay out of the way.** An expanded commit in the Commits tab now caps its message body with a bottom fade and a Show more / Show less toggle, so a long release message no longer pushes the file tree and containing branches off the bottom of the panel.
- fix(acp): **Agents can reach their own files again.** File access over ACP was pinned to the session working directory, so agents that keep state elsewhere failed silently — Grok's plan mode couldn't write its plan and fell back to a shell heredoc. Writes now also cover the agent's own data home and the temp directories, and two new per-agent variables (`CODEG_ACP_FS_POLICY`, `CODEG_ACP_FS_EXTRA_ROOTS`) let you add roots or restore the old strict behavior from the existing settings UI.
- fix(delegation): **Trustworthy delegation status under Codex.** With Codex as the main agent, polling a batch of delegated tasks collapsed into a single anonymous row that printed raw JSON, carried no task id or duration, and showed "done" for tasks that were still running. codeg now unwraps the envelope Codex puts around live MCP results; existing conversations pick this up when you reopen them.
- fix(diff): **Closing a diff no longer throws.** Opening a file while a diff was on screen — or closing a diff tab, or the commit, push, or stash panels — raised an uncaught editor error. The viewer now tears its editor down in the right order.
- fix(workspace): **A cleaner file column.** The tab strip keeps its bottom hairline even when a long diff title overflows its tab, maximizing the file column no longer leaves the panel resize handle drawn through it, and the side-by-side diff finally has a crisp divider between its panes instead of just a blurred shadow.
- chore(acp): **Refreshed the bundled agents.** OpenCode 1.18.5 and Grok 0.2.112.

-----------------------------

# 发布版本 0.21.9

- 功能(Codex):**在设置页配置沙箱与授权策略。** Codex 设置卡片新增「沙箱与授权」分组:授权策略(untrusted / on-request / never,或用五个开关做精细控制)、沙箱模式(只读 / 工作区可写 / 完全访问),以及工作区可写的细节——可写根目录、网络访问与两项临时目录排除。这些是会话的默认策略,也正是 `/goal`、`/review`、`/compact` 实际运行时所依据的配置,而输入框里的协作模式对它们并不生效:过去可能出现「目标」仍被严格限制、同一会话里的普通回合却毫无限制的情况。改动会合并写入 `~/.codex/config.toml`,保留原有注释与格式;一旦变更,正在运行的 Codex 会话会被标记为需要重启。
- 功能(提交历史):**长提交信息不再喧宾夺主。** 「提交」标签中展开的提交,其信息正文现在带底部渐隐并折叠,附「展开 / 收起」切换,长长的发版信息不会再把文件树与所属分支挤出面板底部。
- 修复(智能体):**智能体重新能访问自己的文件。** ACP 的文件读写此前被固定在会话工作目录内,把状态存在别处的智能体因此静默失败——Grok 的计划模式无法写入计划文件,只能退回用 shell heredoc 变通。现在写入范围还包含智能体自己的数据目录与临时目录;新增两个按智能体生效的变量(`CODEG_ACP_FS_POLICY`、`CODEG_ACP_FS_EXTRA_ROOTS`),可在现有设置界面里追加根目录或恢复原先的严格模式。
- 修复(委派):**Codex 下的委派状态终于可信。** 以 Codex 作为主智能体时,轮询一批委派任务会塌缩成一条无名记录,直接打印原始 JSON,既没有任务 id 也没有耗时,还会把仍在运行的任务标成「已完成」。codeg 现在会剥开 Codex 给实时 MCP 结果套的外层信封;已有会话重新打开即可生效。
- 修复(Diff):**关闭 diff 不再报错。** 在 diff 打开的状态下打开文件,或关闭 diff 标签、提交 / 推送 / 贮藏面板,此前都会抛出未捕获的编辑器错误。现在查看器会按正确顺序拆除编辑器。
- 修复(工作区):**更整洁的文件栏。** 标签条即使在长 diff 标题撑满标签时也能保住底部细线;最大化文件栏不再让面板拖拽手柄横穿其上;并排 diff 两栏之间也终于有了清晰的分隔线,而不只是一道模糊阴影。
- 维护(智能体):**刷新内置的智能体版本。** OpenCode 1.18.5、Grok 0.2.112。
@pull pull Bot locked and limited conversation to collaborators Jul 25, 2026
@pull pull Bot added the ⤵️ pull label Jul 25, 2026
@pull
pull Bot merged commit e540a4f into MoozLee:main Jul 25, 2026
7 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant