Drop the preflight sandbox fence. It derived writable roots in the local
process, so under the SSH provider it threw on remote additionalWritableRoots
and compared remote targets against local temp roots; write and edit never
fenced in the tool layer. The provider now refuses a denied operation at
commit, and a commit whose first operation failed without any change rejects
like a preflight refusal so the sandbox escalation path keeps its error code.
Classify FS_ABORTED as unknown: a cancelled remote request rejects while the
provider may still be writing, so no stat comparison can settle it. Document
that a cancelled call receives the registry's abort result like every tool.
Store no diff for creations, matching write, and bound the move source basis
by diffBasisMaxBytes so persisted metadata never holds whole files;
FsMoveOutcome.sourceBefore becomes nullable. Omit deletions from the call
preview and from result diffs without a basis instead of rendering them as
empty creations, and count distinct files in the preview title.
Reject a NUL byte beyond the read sampling window in preflight, name targets
by display path in atomic-write diagnostics, align the apply_patch guidance
with the edit wording and mention delete and move, read the stopped flag and
applied diffs tool-agnostically in the client models, skip the permission-bit
snapshot under root, list fs/delete-intent in the tool catalog, and refresh
the fs-patch description, group README, fs-sandbox summary, and ui-tool README.
Integrate exact origin/master b9bdd062c8ffd3dc234ebea7f5dff55ff26d87ad. Preserve the Session Markdown copy lifecycle and dictionary while adopting the Japanese locale, regenerate the client slot catalog, and add the Japanese quote-removal string required by the merged locale type.
Restore files outside the patch feature to their merge-base state: the
invariant-check refactors across acp, session-controller, client,
compaction, agent-loop, agent, session-title, and subprocess, the cast
baseline edit, and the rescope-vendor skip list added during the merge.
Rename tool-fs.enableApplyPatch to applyPatch, matching the read, write,
and edit switches. Remove the unused collectMutationPaths export and the
unconsumed PatchHunk.contextLineIndices field, including its SSH schema
and fixtures. Report preflight refusals and syntax failures directly
instead of padding every phase with outcome, affectedPaths, and
cancelled fields. Add apply_patch to the shipped tool catalog test.
Fold the default-activation Agent Note into the apply_patch file-editing
note and delete it. Delete the guarded-filesystem-mutations upgrade
guide: every change is additive and all FileSystem subclasses live in
this repository. Trim defensive and reviewer-addressed sentences from
the package READMEs, subsystem docs, FileSystem JSDoc, and the Agent
Note, keeping the English and Chinese pairs aligned.
Bring master 45d1196d3fe into the release/dsh-0.2.1 squash commit of #6247
so the release commit stays an ancestor of master.
Conflict resolutions:
- apps/web/tsconfig.json, tsconfig.host.json: keep the entry-customization
e2e and master's Computer Use e2e entries.
- docs/subsystems/slots.{md,zh.md}: keep both added paragraphs; re-record the
slots, ui-primitives, and ui-workspace README translation pairs.
- ui-sidebar SidebarRoot.tsx and locales.ts: keep the More menu imports and
copy next to master's version-copy toast.
- apps/web/tests/agent-preset-selection.e2e.ts: keep the New Session
blank-reuse assertions, read presets through master's
sessionProjections.checkpoint() instead of the deprecated stateOf().
Follow-ups on master's side:
- ui-sidebar sidebar-root spec: give master's version-copy render the entry
pin props that SidebarRootInjected now requires.
- snapshots/web/steering/trajectory.expected.md: add the More conversation
views trigger to master's new Trajectory golden.
* fix(ui): avoid tooltip trigger overlap when a side fits
* feat(ui): add navigation entry customization
* fix(test): keep tooltip geometry independent of JSX types
* fix(ui): align customization catalogs and integration fixtures
* test(ui): complete customization lifecycle and release integration coverage
* fix(ui): return entry discovery to the installed plugin list
* docs: refresh module graph for entry customization
* build: refresh workspace links for the moved entry customization package
* docs: regenerate catalogs and pairing hashes for the moved entry customization package
* test(web): cover default-loaded entry customization in the Web e2e
* test(ui): describe entry customization as a browser plugin in the host entry spec
* build: order entry customization publication files as workspace constraints require
* test(release): drop the moved entry customization package from the experimental family list
* style(ui): use the shared focus ring color on entry customization triggers
* test(web): re-record goldens for the default-loaded More navigation menus
* test(web): add the More conversation views trigger to the remaining CI-reported goldens
* docs: record region-owned pins for plugin entry customization
* refactor(ui): rebuild entry customization on region-owned pins and More menus
- Each navigation region (left sidebar, Conversation header, right sidebar
guide) persists its own unpinned list under
dsh.slot.manual-order.<list slot key>.v1, filters its own launchers, and
draws its own More button and Menu around its actions slot.
- ui-entry-customization only registers the shared menu rows (entries with
pin buttons, Browse other plugins, Create your plugin) into the three
actions slots and keeps no state.
- Remove ctx.layout.entryVisibility, the plugin store, left-sidebar drag
reordering, and agentPresetNavigation; ui-layout and ui-agent-preset match
release/dsh-0.2.1 again.
- Keep the release <nav> and Conversation tab-bar visibility conditions.
- Move the More glyph into ui-primitives as IconAppsAddOutline{Regular,Medium}.
* docs: compile the entry customization owner props example
* docs(ui): describe the wrapping Conversation tab row in the header comment
* fix(ui): return New Session to the Workspace blank and its unsent draft
- New Session (startSession without options) takes the blank-reuse path
again instead of creating a fresh Session on every call, which hid the
previous blank and its unsent draft since a5c9c2aaeef (#5775).
- A request that names an Agent preset skips blanks listing a different
preset, so Creator entries no longer take over an ordinary draft.
- Record the change in a v0.2.1-rc.2 upgrade guide; the Host refresh of a
stale loaded blank stays deferred (see the Agent Note).
* docs: regenerate the Cordis inspect catalog for New Session blank reuse
* fix(ui): keep the selected entry visible while unpinned
- Left-sidebar rows and View tabs keep the selected entry, with aria-current or aria-selected, until another entry is selected.
- Entry menu Creator action takes no region argument; the registration's region selects the prompt.
- Document the 2px panel-row and 32px View-tab gaps; drop commit hashes from the New Session Agent Note.
* fix(ui): leave a blank of another preset unstaged when starting Creator
startCreatorDraft stages cordis only when the main blank lists no preset or already lists cordis; navigation opens a separate Creator blank otherwise, so a Standard draft blank keeps its preset.
* feat(ui): choose whether a draft prompt replaces, appends to, or keeps an existing draft
- DraftInitializationOptions gains whenDraftExists ('replace' | 'append' | 'keep', default 'keep'); clearPreviousDraft stays and maps to 'replace' only when whenDraftExists is omitted.
- Append adds the prompt as new paragraphs after the existing text and references; attachments stay in every mode.
- The three Create your plugin entries append their regional prompt.
* test(web): align e2e with New Session blank reuse and the visible selected entry
* refactor(ui): share the draft paragraph writer between setDraft and appendDraft
---------
Co-authored-by: Yif <[email protected]>
Co-authored-by: imccyu <[email protected]>
The DeepSeek Search API returns a short `snippet` for display and a longer
`summary` written for model reading. Carry `summary` on `WebSearchSource`,
map it from the Search API, and render it in place of the snippet in
`web_search` output while the search card keeps the snippet.
`tool-web` collapses summary whitespace and caps each summary at the new
`searchSummaryMaxChars` setting (800 characters by default, the upper end of
the guide's typical range; live summaries measured 1,000-2,300). The cut keeps
surrogate pairs intact and ends in an ellipsis. The PTC tool output type gains
the optional field, so the affected system-prompt sidecars are refreshed, and
the web search round now exercises a multi-line summary.
The HTTP fetch provider resolved each hostname, rejected any non-public
answer, and pinned the connection. That refused every page behind
TUN-mode proxies with fake-IP DNS and did not confine a model that has
shell network access. Requests now go through the installed proxy
dispatcher and the system resolver with no address restriction.
HttpFetchResolver and the HttpFetchProvider resolver parameter are
removed; the upgrade guide covers the migration.
Co-authored-by: turtle1999 <[email protected]>
- register() returns the registration's effect disposer with then/catch/finally
attached; the original body moves unchanged into a private acquire(), keeping
synchronous installation and the asynchronous handle handoff.
- Legacy stateOf(session, key) logs one ctx.logger.warn per key per registry;
registration and calls to its result no longer warn.
- Containing an ignored legacy registration failure is deferred and recorded
under Known Limitations.