Commit Graph
22 Commits
Author SHA1 Message Date
imccyu 21586fe28c feat(client): compose session row actions from slot lists
A Session row's "..." menu and its hover buttons become two list slots the
WorkspaceBrowser entry declares, `sidebar.workspaces.session.menu.item` and
`sidebar.workspaces.session.row.action`. The shipped actions register from
apply the way a client plugin does: pin (menu 100, button 200), rename (200),
fork (300), archive (menu 400, button 100). An entry receives only the row
identity, reads the pin and archive sets through Set hooks its own face
injects, decides its own visibility, renders `MenuItemButton` or one icon
button, and dismisses the menu through the slot-level `useMenuOpenState`
hook bound from the row's render occurrence.

Each action's behavior lives in its injected callbacks. `UiWorkspace` gains
`pinSession` and `unpinSession`; the pin write into the saved orders happens
there, through the viewing-store instance the apply creates and hands the
browser's registration as its handle (the ui-layout pattern), reading the
memberships current at completion. The rename dialog and the row-action
notice are `shell.overlay` entries fed by apply-closure observables through
the faces' `hooks`; the archived notice switches the archived filter
directly. WorkspaceBrowser threads no action callbacks, renders no toast,
and hosts no rename dialog; its title double-click raises the same rename
request.

In ui-primitives, `MenuItemButton` is the plain `role="menuitem"` row for
menus whose rows are components: it shares a data row's markup and styling
and needs no shared state, because `Menu` decides the keyboard walk from the
DOM and now runs the post-selection focus return once on the list's click
bubble for every row kind. `Menu` accepts such rows as `children` beside
`items`, which becomes optional together with `onSelect`; `separatorBefore`
lets a row start a group with the same hairline a separator entry draws. The
context-based `MenuAction` goes away with its extension group.
2026-09-20 12:20:24 +08:00
Magolor e5a72d73df feat(client): add extensible session menu actions 2026-09-20 12:17:47 +08:00
Yif e9b928d993 Merge remote-tracking branch 'origin/master' into feat/macos-sidebar-ui-and-drag-refine
# Conflicts:
#	.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.i18n.yaml
#	.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.md
#	.agents/notes/implemented/feature/2026-09-13-macos-hidden-titlebar-vibrancy.zh.md
#	docs/subsystems/slots.i18n.yaml
#	docs/subsystems/slots.md
#	docs/subsystems/slots.zh.md
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css
#	packages/client/ui-conversation/tests/skeleton.client.spec.tsx
#	packages/client/ui-sidebar/README.i18n.yaml
#	packages/client/ui-sidebar/README.md
#	packages/client/ui-sidebar/README.zh.md
#	packages/client/ui-sidebar/src/client/HeaderLeadingControls.tsx
#	packages/client/ui-sidebar/src/client/index.ts
#	packages/client/ui-sidebar/tests/apply.client.spec.tsx
#	packages/extensions/cordis-client-runner/src/client/slot-catalog.ts
2026-09-18 18:34:12 +08:00
07akioni 21c347913d fix(client): preserve sessionless header geometry across platforms 2026-09-18 11:30:37 +08:00
Yif e9def243e2 Merge origin/master into feat/macos-sidebar-ui-and-drag-refine
Keeps both window-chrome features: this branch's macOS shell.leading seat,
single drag owner, and fullscreen sync alongside upstream's Windows desktop
titlebar (#4407). ipc.ts and preload-app.ts merge both platforms' channels
and preload wiring; Tooltip merges upstream's suppression context with this
branch's pointer-focus suppression; slot-catalog regenerated.
2026-09-18 11:27:06 +08:00
Yif 8019d37d3f feat(client): frame-owned macOS window chrome with single drag owner
One 52px leadingBand in the AppFrame (frame's first child) plus the sidebar
logoRow are the only -webkit-app-region drag surfaces; everything interactive
subtracts itself through two global base.css rules (interactive elements and
body > :not(#root) overlay portals), so header controls, breadcrumb chips, and
strip tabs stay clickable under the band. A ui-theme stylesheet gate pins the
two-file drag allowlist. The frame publishes --dsh-frame-top-clearance (48px)
for entry pages (plugin manager list and detail) beside the existing
--dsh-frame-leading-clearance, replacing per-page hardcoded insets. The
shell.leading window-chrome seat moves the collapsed-sidebar reopen controls
from the conversation header to the frame. Sidebar vibrancy tint drops the
blue cast in dark mode and halves its fill opacity, light mode softens the
blue mix, and the logo row tightens 4px above New Session.
2026-09-18 11:08:13 +08:00
07akioni 1628e911c8 fix(client): keep sidebar navigation available without a session 2026-09-17 19:38:57 +08:00
Yichen Jiang f6428a164e feat(web): keep submitted plans in chat and open them in sidebar 2026-09-17 13:39:31 +08:00
imccyu 2438bdd4d6 docs(client): document explicit Session ownership 2026-09-17 05:28:58 +08:00
Yichen Jiang 90af3110b7 feat(web): host plugin configuration on the Plugins page
The Plugins page declares three slots as children of its main entry:
`plugins.item` lists an official plugin's page in the Official group,
`plugins.bundle.config` renders a bundle's own form on its page, and
`plugins.row.config` gives a row a configure control opening the row's
page. Every entry renders in the `summary` and `page` views the page
passes as owner props; the page draws the title, icon, and crumb and
projects the ledgers beside its store, naming no configurable plugin.

`ui-settings-plugins` registers its four host-plane pages into
`plugins.item` while the Host serves their namespaces and withdraws them
when it stops; the forms keep edits until a save and drop them on leaving
the page, so the discard control and the unsaved marker are gone. The
Settings section becomes the Built-in plugins shell around the inventory
tab, and `settings.plugin.item` is retired.

The Official group opens with the optional bundles the installation
ships, tagged Beta where the feature is one and without an official tag,
followed by the configuration pages. Auto review leaves the optional
bundles and the CLI's dependencies; the install guide names it as its
example spec. The version tag is a capsule like the other tags.

The `plugin-config` web lane drives the pages through the real wire and
opens a community fixture's row page after switching its bundle on; the
settings lanes re-record the renamed navigation entry.
2026-09-16 21:05:34 +08:00
07akioni b43e85129c Merge macOS hidden titlebar while preserving local Web startup 2026-09-15 13:58:23 +08:00
Yif f2db686404 feat(desktop): macOS hidden titlebar with vibrancy sidebar
hiddenInset titlebar with traffic lights over a vibrancy sidebar, darwin-only
via data-platform set by the desktop preload: transparent chain to the window
material, native-theme sync from the app theme source, sidebar top strip +
full hide when collapsed with reopen controls in the new
conversation.session.header.leading slot, title-row drag regions, and
fullscreen right-sidebar traffic-light clearance via the dockkit strip inset.
2026-09-15 02:26:57 +08:00
Yichen Jiang 4012092d24 feat(web): launch terminals from provider guide menus 2026-09-14 19:22:22 +08:00
pku-xht 0eb0e8c770 Merge master to restore required CI for Auto review 2026-09-09 05:25:20 +08:00
pku-xht 55e53907ab feat(permission): add experimental Auto review 2026-09-09 04:36:19 +08:00
imccyu 713b1aacad docs(client): synchronize panel navigation APIs and contracts 2026-09-09 00:26:40 +08:00
imccyu fbbcbf33fe docs(client): document global main-panel extension points 2026-09-09 00:26:34 +08:00
imccyu 508831624f chore(web): assemble Sidebar domains and register workspace packages 2026-09-07 21:29:41 +08:00
Chinesezjc a4d4404708 feat(ui-tool): render read_image results as the image
A settled top-level `read_image` call printed its raw attachment object as
literal text in the tool card — `{"type":"image","attachment":{…}}` —
instead of the image, because no presentation metadata told a client card
how to present the reference and the tool-card layer had no image concept.

Host: `read_image` declares an `output.presentationMeta` persisting
`{ path }` only. The attachment reference deliberately lives in the
settled result content — the single record a `tools/post-execute`
replacement rewrites — not in `meta`; the id is opaque and
provider-owned, checked for existence only.

Client: `imageCardModel` derives the card from the call head, the meta
path, the result's own image block, and a shape-matched envelope. ToolRow
gains an `image` card slot; the `read_image` toolview declares the
Tool-owned `tool.call.images` slot as its child and dispatches the
gallery through it. ui-chat down-threads the session-authorized loader
(`ChatNodeOwnerProps.loadImage`), so the tool layer supplies only derived
references plus the loader and never imports an attachment
implementation; ui-attachment fills the slot with its message gallery
renderer. The card keeps the envelope text below the gallery for the
no-attachment-plugin deployment. An image-bearing tool registers a keyed
toolview; the generic fallback keeps its flattened text. `read_image`
joins the read variant with its own locale title key; both rows share
`read-family-row.tsx`.

Verification: `read-image.spec.ts` (metadata projection, envelope by
shape, reference narrowing, real-execution round trip, rejection
branches incl. non-digest ids), `image-card.client.spec.tsx` (derivation,
row render site dispatching the slot, keyed registration with the
child-slot declaration, empty-slot fallbacks, media-type enum), keyless
snapshots (`read-image-gif` added; read-image/-dimension/-reencode
updated to the `{path}` meta), five injected-defect negative controls,
and a demo GIF recorded from this PR's head through the official
image-capable model.
2026-08-29 17:41:05 +08:00
Yichen Jiang bf0db65bb0 fix(ui-settings-models): address review — derived key fact, required render seat, spec sync
The provider-card seat's keyConfigured now derives from the reference the
page would use — the profile's apiKeyEnv, or the page's derived
<ROUTE>_API_KEY while the profile names none — so the add-provider draft
agrees with its own editor about an existing conventional credential (the
store joins the derived describe in the same batched call, as
ProviderRow.derivedCredential). ModelsSectionProps makes the renderSlot seat
required so a direct render that forgets it fails to compile; the one such
render in provider-form.client.spec regained a real mount and the test
boilerplate collapsed to renderSlot={() => null}. The extension-slots Agent
Note now states the keyed cell's real override rule (same priority throws,
a different priority shadows), and docs/subsystems/slots.md carries the two
new seats in its hierarchy, both languages.
2026-08-26 17:12:58 +08:00
creatixchu d420292400 fix(web): 处理评审发现的图片记录边界情况
- 图片错误结果在 Result 页签保留错误名称与代码
- 空文本块加图片的记录按纯图片标注,不再空行
- sourceBlock 的持久化图片守卫检查 attachmentId 字段
- 移除 ui-chat 对 util/crypto 的过期 tsconfig 引用
- 同步 slots.md 层级图与 2026-08-20 所有权 Note
2026-08-24 18:58:25 +08:00
imccyu 3e942e5e21 docs(client): document web architecture 2026-08-24 01:27:48 +08:00