Commit Graph

4926 Commits

Author SHA1 Message Date
NI0317
3da219461c Merge origin/master into codex/sandbox-policy-context 2026-07-31 15:03:11 +08:00
imccyu
ef01e2e9af Merge pull request #1046 from deepseek-harness/worktree-infdev01
Shared anonymous user id from $DSH_HOME/.userid, reported as OTel Resource user.id
2026-07-31 14:49:00 +08:00
imccyu
06fc3c68a6 Merge pull request #1039 from deepseek-harness/worktree/composer-scroll-sync
fix(web): scroll the composer's glyph layer with its textarea
2026-07-31 14:48:41 +08:00
imccyu
5dcb096015 Merge pull request #997 from deepseek-harness/worktree/chat-ui-polish
fix(web): polish chat activity and queue states
2026-07-31 14:45:23 +08:00
creatixchu
a2c5f7dc0a Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 14:32:14 +08:00
Chinesezjc
538488506f Merge pull request #973 from deepseek-harness/feat/read-presenter
feat(fs): add a read render-intent card for the read tool result
2026-07-31 14:30:31 +08:00
imccyu
bff581ffb3 feat(telemetry): anonymous user id from $DSH_HOME/.userid, reported as OTel Resource user.id
session-telemetry-otel owns the identity as its own module (src/user-id.ts):
getOrCreateAnonymousUserId() returns the bare UUID line in $DSH_HOME/.userid,
minting a random UUID v4 on first use — synchronous IO with a process-lifetime
memo keyed by resolved path, an exclusive-create (wx) settle for concurrent
first launches, best-effort on read-only homes, and deletion resetting the
identity on the next launch by design.

The backend carries the id as the Resource's user.id (the OTel semconv user
attribute), once per export batch alongside service.name/service.version.
The identity belongs to the OTel feed alone; the dsh-sdk launcher telemetry
keeps its own separate store.
2026-07-31 14:28:03 +08:00
creatixchu
22d6b1ed81 Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 14:26:51 +08:00
Yichen Jiang
a2a79ada82 test(web): scope retry status assertion 2026-07-31 14:18:47 +08:00
Yichen Jiang
e0e48bfc10 Merge remote-tracking branch 'origin/master' into worktree/chat-ui-polish
# Conflicts:
#	apps/web/tests/snapshots/live-interactions/retry.expected.md
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-31 14:16:51 +08:00
imccyu
f5680ffabe fix: ci 2026-07-31 14:08:13 +08:00
imccyu
b8b5403f0a fix: ci 2026-07-31 14:08:13 +08:00
imccyu
d2dff40560 feat(ui-workspace): blank New Session rows render no menu and no time
A blank row is a provisional placeholder: nothing has happened in it,
so the row verbs (rename/fork/archive) and a 'now' stamp would act on
content that does not exist. The trailing cells and the hover card's
time line stay off until the first prompt lands.
2026-07-31 14:08:13 +08:00
imccyu
9ed87a6dba refactor(client): archivedSessionIds public face becomes a plain array
Public snapshot state stays in the store engine's plain-data vocabulary
(immer drafts reject Sets without the MapSet plugin, which stays off):
manager/service/contract carry readonly SessionId[] in Host order, and
the tree derivations build their own transient Set — the
expandedProjects pattern. Membership-unchanged installs still keep the
array reference for Object.is short-circuits.
2026-07-31 14:08:13 +08:00
imccyu
d3e8f17a54 fix: review follow-ups for the session archive set
- WorkspaceRegistry.archiveSession no longer wraps persistence-listing
  failures as WorkspaceUnknownSessionError: only a definite miss (live
  lookup, header index, then a fresh list) maps to session-not-found;
  storage faults propagate as internal errors, with a negative test.
- The archived-current sweep moves from the unary path into the
  projection: any install path (local echo, another tab's frame, a
  reconnect baseline) clears a selection that landed in the archive set.
- An archive set installed while workspace.list is in flight supersedes
  the stale baseline's set instead of being rolled back by it.
- The workspace-management e2e anchors the archived row by its session
  actions button and asserts the single-stray fixture assumption loudly.
- Drop the stale touchSession rows from the workspace READMEs (the
  method was removed with its Agent Note).
2026-07-31 14:08:13 +08:00
imccyu
c00f0dccda test(test-runtime): cover the archiveSession double's default and stub arms
The default arm builds the next Set outside the immer draft: reading a
Set through a draft requires the MapSet plugin, assigning a fresh Set
does not.
2026-07-31 14:08:13 +08:00
imccyu
fc0042e47e fix(client-runtime): never reuse an archived blank session in connectWorkspace
Reusing one would open a session no grouping surface can show; the New
Session flow mints a fresh blank instead.
2026-07-31 14:08:13 +08:00
imccyu
3b86c288d6 docs: catalogs and Agent Note for the session archive set 2026-07-31 14:08:13 +08:00
imccyu
e235be2bac feat(ui-workspace): archive session from the row menu
The visual-only Delete session placeholder becomes a wired Archive
session action: no confirmation dialog (non-destructive), failures stay
console diagnostics. tree.ts hides archived sessions in every
derivation (workspace groups, Ungrouped, search, flat list) through the
sessionVisible predicate. The workspace-management e2e pins the archive
round trip across reload.
2026-07-31 14:08:13 +08:00
imccyu
c764ed7e64 feat(client-runtime): project the archive set and the archiveSession action
WorkspaceListState gains archivedSessionIds (ReadonlySet, replaced only
on membership change), installed as full snapshots from the list
baseline, the unary echo, and the changed frame. Archiving the current
session clears the selection into the New Session view state. Test
doubles (test-runtime, fake APIs, fixture client) follow the widened
IWorkspaces/IApiClient faces.
2026-07-31 14:08:13 +08:00
imccyu
53ceab53b8 feat(apiproxy): workspace.archiveSession RPC and archived-sessions frame
workspace.archiveSession answers the full updated archive set;
workspace.list carries the set as the reconnect baseline; the host
stream pushes host/archived-sessions-changed full snapshots from the
domain/changed global-put branch (same posture as workspace-changed).
Unknown sessions map to the existing session-not-found code.
2026-07-31 14:08:11 +08:00
imccyu
b00cd0cd8c feat(workspace): add registry-global archivedSessionIds set
The workspace domain global singleton gains archivedSessionIds (schema
default [], version unchanged): a display-layer archive set layered over
workspace accounting. archiveSession() rides the registry operation
chain, validates the session against live/persisted headers, and is
idempotent; archived sessions keep their sessionIds slot so a future
unarchive restores position.
2026-07-31 14:07:51 +08:00
creatixchu
dec1950b6a Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 14:07:04 +08:00
Yichen Jiang
6acdb6631d Merge pull request #1036 from deepseek-harness/worktree/permission-default-settings
feat(permission): configure new-session defaults in Web settings
2026-07-31 14:05:00 +08:00
Chinesezjc
fe7ae124b7 Merge remote-tracking branch 'origin/master' into feat/read-presenter 2026-07-31 13:55:00 +08:00
Tianyi Cui
da541c10a7 docs: align runtime-context contracts 2026-07-31 13:49:41 +08:00
Tianyi Cui
e088cfa59d refactor(sandbox-policy): remove capability family registries 2026-07-31 13:49:41 +08:00
Tianyi Cui
e6407477a7 fix(agent-loop): clear compacted runtime context 2026-07-31 13:49:40 +08:00
creatixchu
676fee485a Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 13:46:05 +08:00
Tianyi Cui
cff0e5d9a4 Merge master into codex/sandbox-policy-context 2026-07-31 13:45:37 +08:00
Yichen Jiang
8ab6473660 test(permission): cover settings confirmation paths 2026-07-31 13:45:22 +08:00
Yichen Jiang
75f2489ba1 Merge pull request #1031 from deepseek-harness/worktree/fix-models-settings
fix(web): improve Models settings presentation and safety
2026-07-31 13:44:11 +08:00
Yichen Jiang
7aa126e0d5 test(session): expect empty fork seed marker 2026-07-31 13:36:40 +08:00
Tianyi Cui
4535782742 Merge master into codex/sandbox-policy-context 2026-07-31 13:31:13 +08:00
Yichen Jiang
cb60e1759a Merge remote-tracking branch 'origin/master' into worktree/permission-default-settings
# Conflicts:
#	packages/host/apiproxy/README.i18n.yaml
2026-07-31 13:27:43 +08:00
Yichen Jiang
48152a7a1d merge master and address permission settings review 2026-07-31 13:24:30 +08:00
creatixchu
52d6c487b7 Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 13:22:52 +08:00
imccyu
9aa867b6ea Merge branch 'master' into fix/command-execute-transport-timeout 2026-07-31 13:18:12 +08:00
creatixchu
23c4745560 fix(web): assert the wrap-width premise instead of reserving a gutter
Review flagged that "equal by construction" rested on an engine behaviour I
had not measured: `scrollbar-gutter: stable` only equalizes the layers if the
engine applies it to `overflow: hidden` the way it does to `overflow-y: auto`.
Measured it on the running app across the three engines Playwright ships,
and the property does not hold up.

  engine    .input / .backdrop / .mirror wrap width
  chromium  776 / 776 / 776   (768 / 768 / 768 with the declaration)
  firefox   776 / 776 / 776   (unchanged by it — overlay scrollbar)
  WebKit    768 / 776 / 776   (unchanged by it)

WebKit reserves for `overflow-y: auto` and not for `overflow: hidden`, so the
declaration left .input at 768 against 776 — exactly the gap it was meant to
close — on the one engine where that gap is observable at all, while costing
every chromium user 8px of text column unconditionally. Reverted: the
composer's metrics are now the same as before this PR.

The WebKit gap predates this change and is not closed here. It is recorded in
the Agent Note with the numbers, and the browser scenario asserts the equality
on the lane's engine so a regression into that state fails loudly. The mirror
is unaffected on WebKit for the drafts measured — the extents still agree — but
a draft whose wrapping turns on those 8px would clamp it.

The review's monotonicity concern resolves the same way: the declaration was
never worse than master, because WebKit already measured 768 against 776
without it. It simply was not better.

Also from this round: the wrap-width assertion now covers .mirror as well as
the two glyph layers — it is the height authority, so a mirror alone wrapping
wider would measure the box short and clip content below the 14-line cap with
every other assertion green. Plus `renderGeometry`'s missing `@param
trailingNewline`, and both e2e tsconfig lists restored to alphabetical order.
2026-07-31 13:13:50 +08:00
imccyu
eacd24d66a Merge branch 'master' into feat/web-diff-card 2026-07-31 13:07:51 +08:00
Tianyi Cui
fbf28700af Merge master into codex/sandbox-policy-context
# Conflicts:
#	apps/web/tests/snapshots/live-interactions/retry.expected.md
#	apps/web/tsconfig.json
#	tsconfig.host.json
2026-07-31 13:04:21 +08:00
Chinesezjc
a2fa8ccbcf Merge remote-tracking branch 'origin/master' into feat/read-presenter 2026-07-31 13:03:05 +08:00
Chinesezjc
64c855737d Merge remote-tracking branch 'origin/master' into feat/web-diff-card
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/README.md
#	packages/client/ui-conversation/README.zh.md
2026-07-31 12:50:58 +08:00
Yichen Jiang
f45b6f76a5 fix(web): remove tool-call settings placeholder 2026-07-31 12:48:39 +08:00
Yichen Jiang
ee74b5b07a feat(permission): add new-session default setting 2026-07-31 12:48:19 +08:00
imccyu
68a99cf75c Merge branch 'master' into codex/responsive-queue-panel 2026-07-31 12:44:53 +08:00
creatixchu
2143361195 fix(web): reserve one scrollbar gutter across the composer's text layers
Second review round escalated the wrap-width divergence from a separate
concern to a defect in this fix's own premise, and it is right.

Only .input scrolls, so only .input loses content width to a scrollbar that
consumes layout space — what Windows and Firefox draw, and what the theme's
global `::-webkit-scrollbar` width makes chromium treat as occupying space.
A narrower .input wraps a long soft-wrapped draft onto more lines, so it
grows taller, its scroll maximum exceeds the backdrop's, and the mirrored
offset clamps below the caret. That is the same failure the trailing-line
sentinel fixes, in the same direction, so deferring it would have shipped a
fix that does not hold where users run a classic scrollbar.

My first attempt to reproduce it found nothing and was wrong: the probe
content was not wrap-sensitive. With varied-length words the effect is
plain — the same draft laid out at 8px-apart widths differs by 2 to 5
lines, while at equal widths a textarea and a div agree exactly.

The three layers now reserve the gutter together, in the shared metrics
block that already exists to keep them symmetric. `overflow: hidden` is
still a scroll container, so the non-scrolling layers honour it: 8px is
reserved on each, measured. The cost is a text column 8px narrower on every
platform, which is the price of one geometry rather than a per-platform one.

The browser scenario asserts the premise directly — equal wrap widths, and a
reserved band greater than zero on each layer. The band is what stops the
assertion being vacuous: the widths would also match with no reservation at
all on this engine's overlay scrollbar, and it is the reservation, not the
match, that carries the guarantee to a platform whose scrollbar takes real
width. Removing the declaration fails it with `expected 0 to be greater
than 0`, and fails the golden with it.

Also from the same round, three comment corrections: the e2e file header no
longer describes the deleted layout effect, the measurement guard no longer
claims the backdrop holds exactly one text node (the sentinel makes a
second), and the sentinel comment now carries the one-sidedness argument
that also settles the ghost hint — the mirror only fails when the backdrop
is SHORTER, and the hint can only add content, never remove a line box.
2026-07-31 12:39:52 +08:00
Wenlu Wang
4e345c38a9 Merge branch 'master' into codex/responsive-queue-panel 2026-07-31 12:34:57 +08:00
imccyu
5afdb5c235 Merge remote-tracking branch 'origin/master' into mergebot/pr998
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-31 12:23:03 +08:00
creatixchu
f8ef2cf36b fix(web): give the backdrop the trailing-line sentinel so the layers share one extent
Review caught a real divergence the earlier measurements missed: mirroring
an offset is only correct while both layers can reach it, and for a draft
ending in a newline the backdrop could not.

A textarea reserves a line box for the caret after a final newline.
`white-space: pre-wrap` collapses a text node's trailing newline and
generates none. So a draft ending in a newline made the backdrop exactly one
line shorter than the textarea — measured 628 against 652 — and the mirrored
assignment clamped, leaving the glyphs one line behind the caret at the very
bottom of the draft.

The backdrop now carries the same trailing-line sentinel the mirror div has
carried all along: its content is the decoration walk plus one newline. The
same pre-wrap collapse absorbs it when the draft does not end in a newline,
so it costs no height in the ordinary case, and it supplies the missing line
box when it does. Verified in isolation first: a bare pre-wrap div measures
180/180/198 against a textarea's 180/198/216 for zero, one and two trailing
newlines, and 180/198/216 with the sentinel.

Coverage for the shape that exposed it: the browser scenario asserts the two
extents are equal before asserting the glyphs reach the end, observing each
layer's maximum by asking for an impossible offset and reading back the
clamp rather than computing it from scrollHeight, and the golden records the
relation. The unit spec pins the backdrop's text as the draft plus exactly
one newline. Removing the sentinel fails both, the e2e with the same 628
against 652.

The scrollbar-gutter half of the same review point does not reproduce here:
both layers measure clientWidth 776 against a border box of 776 while the
draft overflows, so this engine's textarea scrollbar is an overlay and takes
no width out of the wrap.
2026-07-31 12:12:54 +08:00