Commit Graph

1259 Commits

Author SHA1 Message Date
Chinesezjc
21cd241177 refactor(ui-conversation): extract shared toolview row-status helpers
SearchRow (this PR) and FileMutationRow (landed on master) independently carry
byte-identical rowStateStatus + rowResultText helpers, which the duplication gate
flags once both are present. Extract both into contract/toolview-status.ts and
consume them from both rows, deleting the clone rather than nudging it under the
threshold.
2026-07-31 16:04:45 +08:00
Chinesezjc
a7139b651c Merge remote-tracking branch 'origin/master' into feat/web-search-card
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/chat/GenericToolCard.tsx
#	packages/client/ui-conversation/src/client/chat/ToolRow.module.css
#	packages/client/ui-conversation/src/client/chat/ToolRow.tsx
#	packages/client/ui-conversation/src/client/skeleton/DetailsPanel.module.css
#	packages/client/ui-conversation/src/client/skeleton/DetailsPanel.tsx
#	packages/client/ui-conversation/tests/chat-apply.spec.tsx
#	packages/client/ui-primitives/README.i18n.yaml
#	packages/client/ui-primitives/README.md
#	packages/client/ui-primitives/README.zh.md
#	packages/client/ui-primitives/src/index.ts
2026-07-31 15:55:40 +08:00
Chinesezjc
bbb94f18ec Merge remote-tracking branch 'origin/master' into feat/web-read-card 2026-07-31 15:55:39 +08:00
creatixchu
e5563ae433 fix(locale): gate browser detection on window and tolerate a missing languages list
Node >= 21 exposes a global `navigator` reporting the machine's own language,
so gating detection on `navigator` let a non-browser boot of the client tree
resolve to `en` instead of the documented fallback; `window` is the browser
test. `navigator.languages` is spec-required but absent on some embedders and
older WebViews, where spreading it would throw at boot, so the walk tolerates
its absence and `navigator.language` covers that host.

The per-spec pin boilerplate collapses into one suite-level
`usePinnedBrowserLanguages('zh-CN')`, which owns the rationale in
dsh-client-test-runtime, and the English-browser e2e scenario now clears the
console warnings channel too — its page has no closing inventory spec.
2026-07-31 15:49:59 +08:00
Chinesezjc
3ee8b6c1d6 Merge remote-tracking branch 'origin/feat/web-read-card' into feat/web-cards-toolrow 2026-07-31 15:49:31 +08:00
creatixchu
d6231007af cleanup(web): give adding a Workspace one route
Both Workspace surfaces offered "Open local folder…" and "Create a new
workspace" for one outcome. The browse occupant already carries its own
New folder affordance, so picking a directory covered creating one; the
name dialog only added a second vocabulary and a create target the
operator could neither see nor choose.

The surviving entry is named after the outcome — "Add workspace…" — and a
menu now appears only where there is something to choose between: with no
Workspace listed (the add-only sidebar header, or an empty hero list) the
anchor gesture raises the directory flow directly instead of a one-row
popover. An empty list counts as final only after the list baseline lands,
and a composition with no directory-flow occupant hides the sidebar button
rather than offering a dead one.

WorkspaceCreateFlow becomes WorkspacePickFlow (createOnly -> addOnly) and
the injected createWorkspace narrows to { path }. The host's
workspace.create({ name }) branch and `dsh web --workspace-root` lost their
last product consumer; both are marked at the call site for a follow-up.
2026-07-31 15:47:40 +08:00
Chinesezjc
50a625890f fix(web-read-card): mark read-row summary chrome jscpd:ignore
The keyed toolviews (read, file-mutation, web) each draw the same ToolRow
summary-line chrome; the read row's copy trips the duplication gate against the
file-mutation row. Extracting the shared row is a separate change tracked for
all rows at once, so this scopes the exemption to the read row's block.
2026-07-31 15:46:27 +08:00
Tianyi Cui
7906c1032f Merge pinned master into status bar token metrics 2026-07-31 15:41:52 +08:00
creatixchu
8714952c85 feat(web): copy values from hover cards 2026-07-31 15:38:22 +08:00
Hypatia May
1114a80a45 Merge branch 'fix/web-transcript-projection' into feat/manual-compact-single-lock
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
2026-07-31 15:36:49 +08:00
Hypatia May
d67de808b0 Merge remote-tracking branch 'origin/master' into fix/web-transcript-projection
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-31 15:32:36 +08:00
kingwl
4dfbb52106 Merge remote-tracking branch 'origin/master' into codex/fix-tui-diff-context-counts
# Conflicts:
#	packages/ui/tui/src/components/transcript.ts
2026-07-31 15:27:24 +08:00
creatixchu
cb754a0319 feat(locale): derive the initial Settings language from the browser
A first visit resolved to Chinese regardless of the browser: LocaleService
read `dsh.locale` and fell straight back to `zh` when nothing was stored,
ignoring the languages the browser already states it reads.

The initial locale now resolves through three ordered sources — the persisted
preference, then `navigator` (first entry of the ordered language list whose
primary subtag names a shipped locale, so `zh-Hans-CN` -> zh and `en-GB` ->
en), then `FALLBACK_LOCALE`. An explicit choice still wins and nothing writes
the detected locale back to storage, so "has the user chosen?" stays a
question only the stored value answers.

Specs asserting the shipped Chinese copy now state the browser they assume:
the web e2e scenarios open their page with `locale: ZH_BROWSER_LOCALE`, and
package specs pin it through the new `pinBrowserLanguages` test helper.
`settings-chrome.e2e.ts` gains an English-browser scenario as the
assembled-app proof.
2026-07-31 15:26:46 +08:00
creatixchu
49f8cdd401 fix(web): bind the composer's caret to its glyphs with one scrollport
The composer paints its draft in two layers — the textarea owns the value,
the selection and the caret, the backdrop paints every visible glyph — and
they had one scroll offset each, kept equal by a `scroll` listener. That
holds at rest and not in motion: a wheel gesture scrolls the textarea on the
compositor, the listener runs afterwards, and for those frames the caret sits
at the new offset with the words at the old one. Measured on a harness of the
same geometry, a 200px offset change separates caret from glyphs by ~200px
(chromium 203, firefox 202, WebKit 203) until a later frame — the caret
flying out of its own text when a user swipes a long draft quickly.

Both layers now ride one scrollport: `[data-input-scroll]` carries the
14-line cap, the auto-grow stack inside it is as tall as the whole draft, and
the textarea holds no scrollable overflow of its own. The browser applies one
offset to both layers in the same frame, so the coupling is structural rather
than maintained. The backdrop's trailing-line sentinel and the cross-engine
wrap-width premise go with the mirror: the layers now share a containing
block, which closes the WebKit 768-against-776 gap by construction.
2026-07-31 15:25:29 +08:00
creatixchu
6ca3b78e55 Merge remote-tracking branch 'origin/master' into worktree-session-hover-menu-fix
# Conflicts:
#	apps/web/tests/workspace-management.e2e.ts
2026-07-31 15:14:05 +08:00
Chinesezjc
b140590451 fix(web-read-card): add archivedSessionIds to read-card.spec workspace state
The master merge added a required archivedSessionIds field to WorkspaceListState;
the read-card spec's DetailsPanel fixture state needs it to typecheck.
2026-07-31 15:10:19 +08:00
creatixchu
51fd1d2b41 fix(web): only anchor presses dismiss the hover card
The card is a React child of the wrapper, so capture-phase presses on it
reached the wrapper's dismissal handler: the first pointerdown of a text
selection closed the card, contradicting its JSDoc contract. Restrict the
immediate close to presses outside the card, keeping it mounted under a
held press (and the browser click with it), and align onPointerLeave's
grace arming with Menu (only while open).

Pin both new behaviors in hover-card.spec and update the bilingual Agent
Note.
2026-07-31 15:06:27 +08:00
NI0317
d3ff2c3653 docs(onboarding): update internal testing notice 2026-07-31 15:04:24 +08:00
imccyu
95c238a74f Merge remote-tracking branch 'origin/master' into mergebot/pr1016 2026-07-31 14:51:15 +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
Chinesezjc
b155051d48 Merge remote-tracking branch 'origin/master' into feat/web-read-card
# Conflicts:
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/chat/GenericToolCard.tsx
#	packages/client/ui-conversation/src/client/skeleton/DetailsPanel.tsx
#	packages/client/ui-conversation/tests/chat-apply.spec.tsx
#	packages/client/ui-primitives/src/index.ts
2026-07-31 14:46: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
imccyu
4c01550833 Merge remote-tracking branch 'origin/master' into mergebot/pr1016 2026-07-31 14:43:03 +08:00
Tianyi Cui
e371311203 Merge latest Web transcript parent into manual compaction
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/client/runtime/README.i18n.yaml
2026-07-31 14:39:20 +08:00
Tianyi Cui
5c394b1743 Merge latest master into web transcript projection
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
2026-07-31 14:31:14 +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
_Kerman
b57291d272 Merge branch 'master' into xtr/trajectory-timeline-polish 2026-07-31 14:12:13 +08:00
Tianyi Cui
6a31f5bf2a Merge finalized Web transcript parent
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-30-session-end-seed-log-boundary.i18n.yaml
2026-07-31 14:11:40 +08:00
_Kerman
e11f858357 Merge remote-tracking branch 'github/xtr/trajectory-timeline-polish' into xtr/trajectory-timeline-polish 2026-07-31 14:10:04 +08:00
_Kerman
d9d1c3e079 fix(trajectory): use runtime preference persistence 2026-07-31 14:09:56 +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
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
Tianyi Cui
74398e87f6 Merge latest master into Web transcript 2026-07-31 14:07:24 +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
Tianyi Cui
0592da73ea Merge finalized Web transcript parent 2026-07-31 13:56:32 +08:00
Tianyi Cui
bb3c0d127d Merge latest master into Web transcript 2026-07-31 13:50:34 +08:00
creatixchu
676fee485a Merge remote-tracking branch 'origin/master' into worktree/composer-scroll-sync 2026-07-31 13:46:05 +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
Tianyi Cui
98f48fd83a Merge finalized Web transcript parent
# Conflicts:
#	apps/cli/README.i18n.yaml
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-trajectory/README.i18n.yaml
#	packages/client/ui-trajectory/README.zh.md
2026-07-31 13:42:47 +08:00