Commit Graph
140 Commits
Author SHA1 Message Date
Chinesezjc 75ae2cb4eb Merge remote-tracking branch 'origin/master' into feat/scrollbar-tokens 2026-07-28 16:23:44 +08:00
imccyu 0b1a8b3fee fix: ci 2026-07-28 15:25:38 +08:00
Chinesezjc c3e9690b2e fix(ui-theme): gate the standard scrollbar properties behind the missing WebKit pseudo-element
A non-`auto` `scrollbar-width` or `scrollbar-color` makes Chromium and Safari
discard every `::-webkit-scrollbar*` rule for that element, including
`::-webkit-scrollbar-thumb:hover`. Declaring both unconditionally left the
hover tokens rendering nowhere: the engines implementing the hover
pseudo-element are exactly the ones the standard properties silence, and
Firefox has no hover pseudo-element to fall back on. Both hover tokens and all
four elevated surfaces' hover rebinds were therefore dead code.

Measured in chromium on probe elements with `scrollbar-gutter: stable`: an 8px
`::-webkit-scrollbar` alone reserved a 30px band, and adding
`scrollbar-width: thin` dropped it to the 10px `thin` reserves.

The standard properties now sit inside `@supports not
selector(::-webkit-scrollbar)`, so Firefox takes them and WebKit-based engines
take the pseudo-elements. The WebKit rules stay ungated: an engine without
those pseudo-elements drops them as unknown selectors, and gating them would
hide them from an engine that implements them without `selector()` — the
pre-16.4 Safari the ungated form serves correctly.

Three unit assertions pin the split by source offset, which the existing
at-rule-flattening parser cannot see. The web e2e now reads the path chromium
actually takes: the `auto` standard properties as the gate's signature, the
pseudo-element sizing and track, the indirection variables resolved per
throwaway probe, and the hover declaration as cascade rule text — chromium
folds the `:hover` rule into `getComputedStyle(el,
'::-webkit-scrollbar-thumb')`, so no computed query separates the states.
2026-07-28 15:02:20 +08:00
Chinesezjc a6b0cd6f8d Merge remote-tracking branch 'origin/master' into feat/scrollbar-tokens 2026-07-28 13:43:11 +08:00
Chinesezjc a031967181 test(web): register the sidebar scrollbar e2e on the host plane
Every scaffold-importing e2e compiles on the host plane, so the new file
goes in tsconfig.host.json's include list and apps/web/tsconfig.json's
exclude list. Without both, tsc -p apps/web/tsconfig.json fails with
TS6059/TS6307.
2026-07-28 11:06:03 +08:00
Chinesezjc 662089dd76 fix(client): theme the scrollbars and reserve the workspace list gutter
design-platform.css declared four --dsw-alias-scrollbar-* tokens in both
palettes that no rule read, so every scrolling region rendered the user
agent's own scrollbar and the dark theme showed a light native bar against
dark surfaces.

The symptom that surfaced the gap was in the sidebar: the workspace
browser's session list is its only scrolling region, and each row's
trailing content (the relative timestamp, and the hover action buttons
that replace it) is `flex: none` flush against the row's 8px right
padding, so an overlaid scrollbar painted on top of the timestamp.

ui-theme/styles/scrollbar.css becomes the sole consumer of the four
tokens, imported by the web shell's base.css after design-platform.css
because it reads that sheet's tokens. The rules sit on `body`, not
`html`: the alias tokens are declared on `body`, custom properties
inherit only downward, and from `html` they resolve to the
guaranteed-invalid value with scrollbar-color computing to `auto`.
scrollbar-width and scrollbar-color are declared on `body, body *` rather
than inherited, because inheritance would carry the color already
substituted at `body` and an elevated surface could not retint its own
thumb; scrollbar-width does not inherit at all.

Both the standard properties and the ::-webkit-scrollbar pseudo-elements
read one indirection pair bound to the l1 tokens, so an elevated surface
rebinds that pair to the l2 tokens once and retints both renderings. The
command popup, slash menu, model-select panel, and settings panel do so,
which gives the l2 tokens their first consumers.

WorkspaceBrowser's `.list` declares scrollbar-gutter: stable, keeping the
bar beside the rows. `stable` rather than `auto` so the reservation holds
when the list is short enough not to scroll: expanding a workspace group
would otherwise shift every row sideways at the moment it starts
scrolling.
2026-07-28 11:02:11 +08:00
07akioni fb9495b21e Merge branch 'master' into fix/todo-tool-ui 2026-07-28 10:59:05 +08:00
imccyu af70af4020 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-28 00:39:24 +08:00
Tianyi Cui 064cea4ebe Merge remote-tracking branch 'origin/master' into worktree/pr743-merge-20260727
# Conflicts:
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl
#	examples/cordis-agent/tests/cordis-tools.e2e.ts
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl
2026-07-27 23:59:33 +08:00
Tianyi Cui 7a60a523f9 Merge branch 'master' into feature/cordis-temporary-tools 2026-07-27 22:26:49 +08:00
07akioni 560dc1d8d8 Merge branch 'master' into fix/todo-tool-ui 2026-07-27 22:22:40 +08:00
NI0317 1ef285d038 Restore Cordis mount and unmount names
Keep temporary lifecycle descriptions and UI labels explicit.
2026-07-27 21:20:06 +08:00
Chinesezjc 207bab0c21 Merge remote-tracking branch 'origin/master' into fix/question-composer-row-shrink 2026-07-27 21:11:15 +08:00
Chinesezjc f11dc28f1f test(web): record the user-bubble action row in the answered golden
The answered golden omitted the `复制` / `在新对话中分支` / `编辑` buttons
that `MessageItem`'s `UserActions` renders under every user bubble, so the
scenario failed against the built client. They are unconditional in the
accessibility tree — the `@media (hover: hover)` rule only sets `opacity`,
which does not remove a node from an aria snapshot — so there is no
message-row state to stabilize before capture; the golden was simply
recorded against a stale `lib/`. A partially failed `pnpm run build` had
left the client bundles from before its failure current and the rest not.

The Agent Note records that trap: confirm the build exited zero before
refreshing a golden, and note that untracked directories under `packages/`
are compiled too, so a leftover from another branch fails the build for
reasons the diff does not explain.

The same omission is present in the other 15 committed web goldens on
master, where 9 tests across 7 files fail for this reason on a pristine
tree. That is pre-existing and belongs to whoever landed `UserActions`;
this commit fixes only the golden this PR already touches.
2026-07-27 19:54:55 +08:00
imccyu 6d8e5fb3a2 Merge branch 'master' into worktree/web-session-model-selector 2026-07-27 19:36:19 +08:00
Chinesezjc 9dd57a25c5 fix(ui-question): stop option rows absorbing the capped card's shortfall
The question composer card is capped against the viewport and scrolls its
option list. `.options` is a flex column whose children defaulted to
`flex-shrink: 1`, so a short seat shrank the rows before overflowing the
scroll container: a row collapsed to its 42px minimum while `.optionCopy`
kept the taller height its wrapped copy needs, and `align-items: center`
then painted that copy outside the row's border box — over the question
title above and the next row below. Measured 6.5px of spill at 900x440 on
the shipped client, 10px at 380px tall, with `.options` reporting
scrollHeight === clientHeight and therefore offering no scrollbar.

`.option` and `.custom` now declare `flex-shrink: 0`, so the shortfall
reaches the scroll container that already owns `overflow-y: auto` — the
behavior the cap was designed for. Only rows whose copy wraps could
reproduce this, which is why the recorded scenario now asks a question
with long option descriptions; the web e2e asserts at three squeezed seat
heights that every row's children stay inside its border box, guarded
against holding vacuously by requiring a wrapped row and a scrolling list.
2026-07-27 19:20:33 +08:00
ZiyaZhang fef928a7e1 feat(gui): add native workspace folder picker 2026-07-27 03:50:22 -07:00
fz 826c6fd243 feat(web): present Cordis lifecycle tools 2026-07-27 17:57:59 +08:00
Tianyi Cui d897dcc7ea Merge remote-tracking branch 'origin/master' into worktree/pr682-retarget-20260727
# Conflicts:
#	.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml
2026-07-27 17:55:56 +08:00
07akioni e30f642e37 refactor(todos): update TodoRow styling and logic, add IconChecklistOutline16, and enhance AssistantMarkdown rendering 2026-07-27 17:23:36 +08:00
Yichen Jiang 7f4905c4bf Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/README.zh.md
2026-07-27 17:18:29 +08:00
imccyu a020400286 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-27 17:01:42 +08:00
imccyu 0052ea49ff Merge branch 'master' into feature/delete-workspace 2026-07-27 16:59:28 +08:00
imccyu 50ec3b1db0 Merge branch 'master' into feat/todo-tool-ui 2026-07-27 16:54:34 +08:00
imccyu 5b81025b58 Merge branch 'master' into feature/delete-workspace 2026-07-27 16:52:24 +08:00
07akioni 16598f7159 fix: cr 2026-07-27 16:36:36 +08:00
07akioni 900e45b365 feat: optimize todo tool ui 2026-07-27 16:24:30 +08:00
imccyu 9249c5504e Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-27 16:16:17 +08:00
Yichen Jiang 0d084ab6ff feat(web): support reasoning effort selection 2026-07-27 16:12:40 +08:00
NI0317 dcf06e8272 Merge remote-tracking branch 'origin/master' into feature/delete-workspace
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/host/apiproxy/README.i18n.yaml
2026-07-27 15:54:51 +08:00
NI0317 4701373fc2 fix(workspace): remove transient duplicate warning 2026-07-27 15:52:35 +08:00
imccyu 228d503230 fix: code-mode fixture snapshot 2026-07-27 15:49:37 +08:00
Yichen Jiang 39c60d5d64 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.md
#	.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.zh.md
#	packages/llm/llm-deepseek/README.i18n.yaml
#	packages/llm/llm-deepseek/tests/adapter.spec.ts
2026-07-27 15:49:09 +08:00
Yichen Jiang 181ac52f8e Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/tests/fake-api.ts
#	packages/client/runtime/tests/session.spec.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/README.md
#	packages/client/ui-conversation/README.zh.md
#	packages/host/apiproxy/README.i18n.yaml
2026-07-27 15:41:01 +08:00
Yichen Jiang c3dfed668d Merge branch 'master' into worktree/llm-reasoning-effort 2026-07-27 15:30:00 +08:00
NI0317 7bd96af5eb fix(workspace): make deletion recoverable 2026-07-27 14:37:04 +08:00
imccyu 3b04941830 Merge the concurrent selector adaptation; ui-model stays the model owner
The remote side re-merged master (i18n workflow round) and restored the
pre-architecture ModelSelector package with the Session-side state
machine. Reconciliation keeps that merge's master content and reasserts
this branch's model architecture: business state lives in ui-model's
shared per-session directory (ctx.models), not on Session/
ConversationSnapshot; the input.model seat entry and the /model popup
stay the two same-source entries; the history modelTarget piggyback stays
removed. The ui-model-selector package, its roster row, and its allowlist
entry go; the smoke-real roster names ui-model.
2026-07-27 13:36:25 +08:00
Yichen Jiang 21aeff3029 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml
#	docs/config-catalog.md
#	docs/core-data-structures/session.i18n.yaml
#	scripts/type-equiv.manifest.json
2026-07-27 13:35:10 +08:00
NI0317 187cf6f804 feat(web): delete workspace registrations 2026-07-27 12:38:11 +08:00
Yichen Jiang bde5e26a96 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	apps/cli/package.json
#	apps/web/tests/smoke-real.e2e.ts
#	apps/web/tests/snapshots/fresh-round-trip/ui.expected.md
#	apps/web/tests/snapshots/seeded-history/ui.expected.md
#	docs/config-catalog.md
#	packages/client/connection/tests/fake-api.ts
#	packages/client/runtime/src/client/index.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/runtime/tests/fake-api.ts
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/src/client/skeleton/InputBar.tsx
#	packages/client/ui-conversation/tests/chat-stats-bash-sample.spec.tsx
#	packages/client/ui-conversation/tests/chat-toolview-slot.spec.tsx
#	packages/client/ui-conversation/tests/chat-view.spec.tsx
#	packages/client/ui-conversation/tests/gate-branch-tails.spec.tsx
#	packages/client/ui-conversation/tests/input-bar.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/src/api-proxy.ts
#	pnpm-lock.yaml
#	scripts/verify-package-readme-model-experience.ts
#	tsconfig.base.json
2026-07-27 12:17:38 +08:00
imccyu 8dce7981c4 refresh code-mode trajectory ordinals for the todo fixture turn
Turn 65 (todo_write) at the fx-alpha tail slides the 50-message history
window: two head-of-window messages drop out, so every trajectory cell
ordinal shifts down by two. Timing, labels, and cell content are unchanged.
2026-07-27 11:38:02 +08:00
imccyu 83d3179d34 disambiguate the snapshot's workspace-group lookup
Latest master seeds a blank session also titled "fixture"; anchor the
session-tree lookup on the expandable group row instead of the first text
match.
2026-07-27 10:14:37 +08:00
imccyu dadb92302f adapt todo display to the slash/input/session architecture
- TodoPanel mounts through a 'conversation.input.dock' list entry
  (todoDockEntry, QueueDock posture, order -1 above the queue rows) instead
  of a ConversationRoot hardcode; the inner component is unchanged and takes
  useSession from the dock entry's standard kit.
- The verify-todo-display.mjs chromium probe is replaced by an assembled
  keyless snapshot (apps/web/tests/todo-display.snapshot.ts, the
  code-mode-fixture idiom) pinning the TodoRow summary/state, the dock
  panel content, and the collapse round-trip over built bundles.
- Fake snapshots across specs gain the todos field; bilingual note/READMEs
  updated for the dock mount and the snapshot.
2026-07-27 10:09:42 +08:00
imccyu 1b49666cd5 Merge branch 'master' into worktree-slash-split 2026-07-27 08:54:56 +08:00
imccyu ecdaf0dc24 test(web): connect a Workspace in the e2e boot path and refresh goldens
The startup-selection flow leaves a fresh world (no Workspace) in the
locked view state, so every e2e scenario that types into the composer
now connects one first via the shared connectFreshWorkspace helper
(hero picker create-by-name dialog; the default 'workspace' name keeps
the session-header cwd assertions intact).

Golden refreshes carry the current composer chrome: the plan/model
control seats are empty until their owning plugins register (the seats
shipped without occupants on this branch), the sidebar shows the
connected workspace group pre-send, and the bash details material
renders Input/code/Output as separate nodes. The cancel scenario polls
the frozen-partial swap instead of counting synchronously — the abort
frame reaches the browser over SSE after the host settles.
2026-07-27 08:25:00 +08:00
imccyu 250e2415ae test(web): re-anchor snapshot suites to the startup-selection boot flow
The startup Workspace auto-selection (wired in cd8ed43e4) changed the
boot landing: with any Workspace present the client connects its blank
session directly instead of resting in the locked view state.

- workspace-flow: New Session now reuses the blank session in place
  (no locked interlude); the failed-attach scenario asserts the actual
  recovery semantics — the host publishes the session before rejecting
  attachment, so the next connect reuses it into the hero (connect
  failures log to console, there is no view-state alert surface); the
  rejected-prompt scenario anchors on the sidebar New Session row since
  a send attempt leaves the hero for the engaging retry chrome.
- slash-flow: drop the stale i18n PLUGINS row (the package is locale).
2026-07-27 07:48:07 +08:00
Tianyi Cui cbb266dc2d Merge remote-tracking branch 'origin/master' into nih-imp-execa
# Conflicts:
#	.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml
#	apps/web/tests/scaffold.ts
#	packages/session-persistence/session-checkpoint-policy/tests/crash-recovery.e2e.ts
#	packages/support/acp-snapshot/README.i18n.yaml
2026-07-27 06:31:17 +08:00
imccyu cbe8735d7c feat(web): wire startup Workspace selection and sync docs
- Mount WorkspacesService.startInitialSelection in the runtime apply (the
  one-shot baseline follower shipped in 98633b5aa without a caller): a
  restored current session wins, an explicit clear stays cleared, a failed
  connect retries on the next baseline projection.
- Cover the policy in client-apply and the assembled workspace-flow
  snapshot; startup now lands in the recent Workspace's blank session, so
  the draft-carry scenario starts from the hero directly.
- Bring docs along: startup-selection paragraphs in the session-scope RFC
  note (both languages), bilingual README pairs for the four new client
  packages, doc-graph regeneration with client-declared events exempt from
  the dispatcher requirement (client dispatch sites are structurally
  invisible to the host-side ts.Program), and pairing re-records.
2026-07-27 06:24:09 +08:00
imccyu d1e43fcd8c style: typed queries in slash-flow snapshot, widen chat-apply key union 2026-07-27 04:13:05 +08:00
imccyu f6396f2573 style: fix lint across client packages
eslint --fix autofixes plus manual repairs: max-len line splits
(fake-api handlers, notifier/slots JSDoc, spec signatures), charAt over
non-null-asserted indexing in slash detect/menu cores, Array.from for
code-point capping, typeof assertions for unbound-method in specs,
generic getByRole for the send-button cast, effect disposer void-wrap in
command register, and dropped unused type imports.
2026-07-27 04:13:00 +08:00