From b649304fe4fbb354dc35738261cdda3f28b40321 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:26:48 +0800 Subject: [PATCH] Revert "fix: remove redudant export for client plugin" This reverts commit 48b259100b9cfe2e372eb9fe0924a783988f5a8e. --- packages/client/connection/src/client/index.ts | 11 +++++++---- packages/client/runtime/src/client/index.ts | 10 +++++----- packages/client/ui-conversation/README.md | 2 +- .../client/ui-conversation/src/client/index.ts | 12 +++++++++--- .../tests/skeleton-branches.spec.tsx | 5 +---- .../ui-conversation/tests/skeleton.spec.tsx | 7 +++---- packages/client/ui-layout/README.md | 4 +--- packages/client/ui-layout/src/client/index.ts | 11 +++++------ .../client/ui-layout/tests/app-frame.spec.tsx | 2 +- packages/client/ui-layout/tests/columns.spec.ts | 2 +- packages/client/ui-layout/tests/service.spec.ts | 3 +-- packages/client/ui-sidebar/README.md | 2 -- packages/client/ui-sidebar/src/client/index.ts | 15 +++++++++++---- .../client/ui-sidebar/tests/sidebar-root.spec.tsx | 7 ++++--- packages/client/ui-sidebar/tests/store.spec.ts | 2 +- packages/client/ui-sidebar/tests/tree.spec.ts | 2 +- packages/client/ui-trajectory/src/client/index.ts | 6 ++++-- .../client/ui-trajectory/tests/views.spec.tsx | 11 ++++------- 18 files changed, 60 insertions(+), 54 deletions(-) diff --git a/packages/client/connection/src/client/index.ts b/packages/client/connection/src/client/index.ts index b017d1c9e2..026fc1bf5f 100644 --- a/packages/client/connection/src/client/index.ts +++ b/packages/client/connection/src/client/index.ts @@ -21,13 +21,16 @@ export type { ClientRequest, ServerResponse, ServerRequest, ClientResponse, RpcMessage, RpcReceipt, IApiClient, SessionId, SessionEvent, ContentBlock, StreamChunk, } from './api.ts' -export { RpcId, AbstractApiClient, transportError } from './api.ts' +export { RpcId, AbstractApiClient, resultOf, transportError } from './api.ts' -// ---- Connection loop types (part of the ConnectionHandle.start contract; -// the controller class itself stays package-internal — apply owns the loop, -// tests reach it via src) ---- +// ---- Connection loop ---- +export { ConnectionController } from './connection.ts' export type { ConnectionConfig, ConnectionSinks, ConnectionState } +// ---- Platform client subclasses ---- +export { WebApiClient } from './web-api-client.ts' +export { FixtureApiClient, createFixtureApi } from './fixture.ts' + /** Required services (none — this is the wire root). */ export const inject: string[] = [] diff --git a/packages/client/runtime/src/client/index.ts b/packages/client/runtime/src/client/index.ts index a8ac9d4e51..6c012fa410 100644 --- a/packages/client/runtime/src/client/index.ts +++ b/packages/client/runtime/src/client/index.ts @@ -15,16 +15,16 @@ import { SlotsService } from './slots.ts' import { SessionsService } from './sessions/service.ts' import type { ConversationSnapshot, RunningToolCall, ToolResultNode } from './sessions/conversation.ts' -// Contract face only: implementation internals (SessionManager, Session, -// PAGE_MESSAGES, the lineage/list-snapshot shapes, the block classifier) -// stay package-internal — tests reach them via src, and downstream packages -// consume sessions exclusively through the service + snapshot types below. export { SlotsService } from './slots.ts' export { SessionsService, scopeOf } from './sessions/service.ts' export type { SessionBinding, SessionListState, SessionSummary } from './sessions/service.ts' +export { SessionManager } from './sessions/manager.ts' +export type { SessionListSnapshot } from './sessions/manager.ts' +export { Session, PAGE_MESSAGES } from './sessions/session.ts' +export type { SessionListEntry } from './sessions/lineage.ts' export type { AssistantBlock, AssistantMessageNode, ContextMessageNode, ConversationNode, ConversationSnapshot, - PendingInteraction, RunningToolCall, SteeringMessageNode, + OpenState, PartialAssistant, PendingInteraction, PromptError, RunningToolCall, SteeringMessageNode, ToolResultNode, UnknownSurfaceNode, UserMessageNode, } from './sessions/conversation.ts' export type { SessionId } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/ui-conversation/README.md b/packages/client/ui-conversation/README.md index 425122958a..c75077d11d 100644 --- a/packages/client/ui-conversation/README.md +++ b/packages/client/ui-conversation/README.md @@ -2,7 +2,7 @@ Conversation domain: skeleton (header/tabs/composer/empty state), chat view (grouped step-summary flow, streaming tail isolation), ctx.toolviews named registry with bash samples, minimal details panel, scope-addressed ConversationService. Contract: api-contracts v3 §7. -`src/client/` is organized for the future package split: `contract/` is the sole inter-domain shared face (`slots.ts` composed slot props, `views.ts` view ring, `toolview.ts` tool ring, `tool-call-model.ts`); the `skeleton/`, `chat/`, and `toolviews/` domain directories import contract files and never each other; `apply.ts` is the only assembly point allowed to import all three domains. The `/client` export surface is the contract only — `apply`/`inject`, the two service classes, and the `contract/` type families; implementation components (skeleton, chat rows) stay internal and reach the page exclusively through apply's slot registrations (tests take them via the `./src/*` subpath). +`src/client/` is organized for the future package split: `contract/` is the sole inter-domain shared face (`slots.ts` composed slot props, `views.ts` view ring, `toolview.ts` tool ring, `tool-call-model.ts`); the `skeleton/`, `chat/`, and `toolviews/` domain directories import contract files and never each other; `apply.ts` is the only assembly point allowed to import all three domains. ## Model Experience diff --git a/packages/client/ui-conversation/src/client/index.ts b/packages/client/ui-conversation/src/client/index.ts index d34b12b0d5..17e9ed88a8 100644 --- a/packages/client/ui-conversation/src/client/index.ts +++ b/packages/client/ui-conversation/src/client/index.ts @@ -24,9 +24,15 @@ export type { ConversationInjected, ConversationSlotProps, DetailsInjected, DetailsSlotProps, EmptyStateInjected, EmptyStateSlotProps, } from './contract/slots.ts' -// Skeleton components are implementation detail, not contract: they reach the -// page exclusively through apply's slot registrations. Tests take them via the -// "./src/*" subpath (repo convention for internal symbols). + +export { ConversationRoot } from './skeleton/ConversationRoot.tsx' +export type { ConversationRootProps } from './skeleton/ConversationRoot.tsx' +export { InputBar } from './skeleton/InputBar.tsx' +export type { InputBarError, InputBarProps } from './skeleton/InputBar.tsx' +export { EmptyState } from './skeleton/EmptyState.tsx' +export type { EmptyStateProps } from './skeleton/EmptyState.tsx' +export { DetailsPanel } from './skeleton/DetailsPanel.tsx' +export type { DetailsPanelProps } from './skeleton/DetailsPanel.tsx' declare module 'cordis' { interface Context { diff --git a/packages/client/ui-conversation/tests/skeleton-branches.spec.tsx b/packages/client/ui-conversation/tests/skeleton-branches.spec.tsx index 799a1e1c7f..25808e17c5 100644 --- a/packages/client/ui-conversation/tests/skeleton-branches.spec.tsx +++ b/packages/client/ui-conversation/tests/skeleton-branches.spec.tsx @@ -9,11 +9,8 @@ import { cleanup, fireEvent, render, waitFor } from '@testing-library/react' import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react' import type { UseSession } from '@deepseek-ai/dsh-client-web-react' import type { ConversationSnapshot, SessionId, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client' +import { ConversationRoot, DetailsPanel, EmptyState } from '@deepseek-ai/dsh-client-ui-conversation/client' import type { SelectionTarget, ViewEntry } from '@deepseek-ai/dsh-client-ui-conversation/client' -// Internal skeleton components: src-subpath imports (not part of the /client contract). -import { ConversationRoot } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/ConversationRoot.tsx' -import { DetailsPanel } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/DetailsPanel.tsx' -import { EmptyState } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/EmptyState.tsx' afterEach(cleanup) diff --git a/packages/client/ui-conversation/tests/skeleton.spec.tsx b/packages/client/ui-conversation/tests/skeleton.spec.tsx index 0d54efe1e0..ab23a64389 100644 --- a/packages/client/ui-conversation/tests/skeleton.spec.tsx +++ b/packages/client/ui-conversation/tests/skeleton.spec.tsx @@ -12,11 +12,10 @@ import type { FC } from 'react' import { bindSnapshotSelector, createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import type { UseSession } from '@deepseek-ai/dsh-client-web-react' import type { SessionId, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client' +import { + ConversationRoot, DetailsPanel, EmptyState, +} from '@deepseek-ai/dsh-client-ui-conversation/client' import type { SelectionTarget, ViewEntry, ViewId } from '@deepseek-ai/dsh-client-ui-conversation/client' -// Internal skeleton components: src-subpath imports (not part of the /client contract). -import { ConversationRoot } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/ConversationRoot.tsx' -import { DetailsPanel } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/DetailsPanel.tsx' -import { EmptyState } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/EmptyState.tsx' const sid = (s: string): SessionId => s as SessionId diff --git a/packages/client/ui-layout/README.md b/packages/client/ui-layout/README.md index 69f9d2fa2e..6c935f4b9d 100644 --- a/packages/client/ui-layout/README.md +++ b/packages/client/ui-layout/README.md @@ -2,9 +2,7 @@ Shell plugin: three-column AppFrame (drag handles, concession chain) + ctx.layout viewing-state service (nav, panel widths, persist); defines the sidebar/conversation/details/conversation.empty slots. Contract: api-contracts v3 §5. -Slot declarations use the composed-props entry form (`owner` share, no full `props`): the exported OwnerShare contracts are `SidebarOwnerProps` / `ConvOwnerProps` / `DetailsOwnerProps` / `EmptyOwnerProps` — registrants reference them via `OwnerOf<'sidebar' | ...>` and compose their own injected share locally. No entry declares `children` (declaring it requires the registered component to carry the slots face): no P-I slot component delegates — `conversation.empty` is rendered by the shell's assembly closure, not handed down by ConversationRoot. - -The export surface is the cross-package contract only: the AppFrame trio (+ `AppFrameProps`) consumed by the web shell's assembly, `LayoutService` with its store shapes (`NavState`/`PanelState`/`ViewId`), and the OwnerShare contracts. The concession-chain solver (`computeColumns`) and its geometry constants are package-internal; tests import them from `/src`. +Slot declarations use the composed-props entry form (`owner` share, no full `props`): the exported OwnerShare contracts are `SidebarOwnerProps` / `ConvOwnerProps` / `DetailsOwnerProps` / `EmptyOwnerProps` — registrants reference them via `OwnerOf<'sidebar' | ...>` and compose their own injected share locally. The `conversation` entry authorizes `conversation.empty` delegation through `children`. ## Model Experience diff --git a/packages/client/ui-layout/src/client/index.ts b/packages/client/ui-layout/src/client/index.ts index ceb4ff0b06..e07c5d9896 100644 --- a/packages/client/ui-layout/src/client/index.ts +++ b/packages/client/ui-layout/src/client/index.ts @@ -10,13 +10,12 @@ import type { Context } from 'cordis' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' import { LayoutService } from './service.ts' -// Contract surface only (export-convergence rule: cross-package consumers -// keep a symbol exported; test-only/package-internal symbols live off /src). -// AppFrame trio + AppFrameProps: consumed by the web shell's assembly closure. -// LayoutService: the ctx.layout service class (consumers type against it). -// PanelState rides AppFrameProps' hooks; NavState/ViewId are service-store -// shapes referenced through LayoutService's members. export { AppFrame, CenterColumn, DetailsColumn, type AppFrameProps } from './AppFrame.tsx' +export { + clampWidth, computeColumns, + CENTER_MIN, DETAILS_DEFAULT, DETAILS_MAX, DETAILS_MIN, SIDEBAR_DEFAULT, SIDEBAR_MAX, SIDEBAR_MIN, + type Columns, type PanelInput, +} from './columns.ts' export { LayoutService, type NavState, type PanelState, type ViewId } from './service.ts' declare module 'cordis' { diff --git a/packages/client/ui-layout/tests/app-frame.spec.tsx b/packages/client/ui-layout/tests/app-frame.spec.tsx index 9fae776dc4..dfc49be327 100644 --- a/packages/client/ui-layout/tests/app-frame.spec.tsx +++ b/packages/client/ui-layout/tests/app-frame.spec.tsx @@ -10,7 +10,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, render } from '@testing-library/react' import { createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import { AppFrame, CenterColumn, DetailsColumn, type PanelState } from '@deepseek-ai/dsh-client-ui-layout/client' -import { clampWidth } from '@deepseek-ai/dsh-client-ui-layout/src/client/columns.ts' +import { clampWidth } from '@deepseek-ai/dsh-client-ui-layout/client' /** Observer stub: captures the callback so tests can fire resizes manually. */ let fireResize: (() => void) | null = null diff --git a/packages/client/ui-layout/tests/columns.spec.ts b/packages/client/ui-layout/tests/columns.spec.ts index 66a785e114..49d351a6d4 100644 --- a/packages/client/ui-layout/tests/columns.spec.ts +++ b/packages/client/ui-layout/tests/columns.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest' import { CENTER_MIN, clampWidth, computeColumns, DETAILS_DEFAULT, DETAILS_MIN, SIDEBAR_DEFAULT, SIDEBAR_MIN, -} from '@deepseek-ai/dsh-client-ui-layout/src/client/columns.ts' +} from '@deepseek-ai/dsh-client-ui-layout/client' const open = (width: number) => ({ open: true, width }) const closed = (width: number) => ({ open: false, width }) diff --git a/packages/client/ui-layout/tests/service.spec.ts b/packages/client/ui-layout/tests/service.spec.ts index d5f784fa0c..85d458cf7b 100644 --- a/packages/client/ui-layout/tests/service.spec.ts +++ b/packages/client/ui-layout/tests/service.spec.ts @@ -9,8 +9,7 @@ import { beforeEach, describe, expect, it } from 'vitest' import type { Context } from 'cordis' import { createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import type { SessionId, SessionListState } from '@deepseek-ai/dsh-client-runtime/client' -import { LayoutService } from '@deepseek-ai/dsh-client-ui-layout/client' -import { DETAILS_DEFAULT, SIDEBAR_DEFAULT } from '@deepseek-ai/dsh-client-ui-layout/src/client/columns.ts' +import { LayoutService, DETAILS_DEFAULT, SIDEBAR_DEFAULT } from '@deepseek-ai/dsh-client-ui-layout/client' function makeCtx() { const list = createSnapshotStore({ ids: [], byId: {} }) diff --git a/packages/client/ui-sidebar/README.md b/packages/client/ui-sidebar/README.md index 3e1bfaa11e..25f840ab3d 100644 --- a/packages/client/ui-sidebar/README.md +++ b/packages/client/ui-sidebar/README.md @@ -4,8 +4,6 @@ Sidebar plugin: session multi-level tree (cwd grouping + parentId nesting), sear `src/client/contract/slots.ts` is the single-domain contract file: `SidebarRootInjected` (the registrant's own injected share — tree hook, current-session hook, actions) and `SidebarRootComponentProps = OwnerOf<'sidebar'> & SidebarRootInjected` (the owner share referenced from ui-layout's slot declaration, never re-stated). `apply` registers SidebarRoot cast-free against that composition; the inject factory binds layout/sessions off `RootBinding`. -The `/client` export surface is the plugin body (`apply`/`inject`) plus the contract types only — SidebarRoot, the row components, and the tree/store implementation are internal (the slot registration closes over them; tests import src paths directly). - ## Model Experience None, as the sidebar renders the browser session list; nothing here reaches a model request. diff --git a/packages/client/ui-sidebar/src/client/index.ts b/packages/client/ui-sidebar/src/client/index.ts index 8fd86396db..fab3bc4836 100644 --- a/packages/client/ui-sidebar/src/client/index.ts +++ b/packages/client/ui-sidebar/src/client/index.ts @@ -3,10 +3,6 @@ * sidebar slot; tree derivation materialized in a plugin-owned snapshot * store (pure consumer — no ctx service). Contract: api-contracts v3 * section 6; props composition in contract/slots.ts. - * - * Export discipline: the public surface is the plugin body (apply/inject) - * plus the contract types. Implementation components and derivation live in - * their modules; tests reach them via src paths. */ import type { RootBinding } from '@deepseek-ai/dsh-client-ui-slots' import type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client' @@ -14,6 +10,17 @@ import type { SidebarRootInjected } from './contract/slots.ts' import { createSidebarTreeStore } from './store.ts' import { SidebarRoot } from './SidebarRoot.tsx' +export { + deriveRows, formatRelativeTime, projectLabel, + UNGROUPED_KEY, UNGROUPED_LABEL, + type ProjectRow, type SessionRow, type SidebarRow, type TreeView, +} from './tree.ts' +export { + createSidebarTreeStore, + type GroupBy, type SidebarTreeState, type SidebarTreeStore, +} from './store.ts' +export { ProjectRowItem, SessionRowItem } from './Rows.tsx' +export { SidebarRoot } from './SidebarRoot.tsx' export type { SidebarActions, SidebarRootComponentProps, SidebarRootInjected, SidebarTreeActions, } from './contract/slots.ts' diff --git a/packages/client/ui-sidebar/tests/sidebar-root.spec.tsx b/packages/client/ui-sidebar/tests/sidebar-root.spec.tsx index cdad00f982..db03c672dd 100644 --- a/packages/client/ui-sidebar/tests/sidebar-root.spec.tsx +++ b/packages/client/ui-sidebar/tests/sidebar-root.spec.tsx @@ -10,9 +10,10 @@ import { cleanup, fireEvent, render, screen } from '@testing-library/react' import { act } from 'react' import { createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import type { SessionId, SessionListState, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client' -import { createSidebarTreeStore, type SidebarTreeStore } from '../src/client/store.ts' -import { SidebarRoot } from '../src/client/SidebarRoot.tsx' -import type { SidebarActions } from '@deepseek-ai/dsh-client-ui-sidebar/client' +import { + createSidebarTreeStore, SidebarRoot, + type SidebarActions, type SidebarTreeStore, +} from '@deepseek-ai/dsh-client-ui-sidebar/client' const sid = (s: string) => s as SessionId diff --git a/packages/client/ui-sidebar/tests/store.spec.ts b/packages/client/ui-sidebar/tests/store.spec.ts index 8ded70400c..d0bb3b386b 100644 --- a/packages/client/ui-sidebar/tests/store.spec.ts +++ b/packages/client/ui-sidebar/tests/store.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest' import { createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import type { SessionId, SessionListState, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client' -import { createSidebarTreeStore } from '../src/client/store.ts' +import { createSidebarTreeStore } from '@deepseek-ai/dsh-client-ui-sidebar/client' const sid = (s: string) => s as SessionId diff --git a/packages/client/ui-sidebar/tests/tree.spec.ts b/packages/client/ui-sidebar/tests/tree.spec.ts index 3919a16d23..1b29d460cf 100644 --- a/packages/client/ui-sidebar/tests/tree.spec.ts +++ b/packages/client/ui-sidebar/tests/tree.spec.ts @@ -3,7 +3,7 @@ import type { SessionId, SessionListState, SessionSummary } from '@deepseek-ai/d import { deriveRows, formatRelativeTime, projectLabel, UNGROUPED_KEY, UNGROUPED_LABEL, type SessionRow, type TreeView, -} from '../src/client/tree.ts' +} from '@deepseek-ai/dsh-client-ui-sidebar/client' const sid = (s: string) => s as SessionId diff --git a/packages/client/ui-trajectory/src/client/index.ts b/packages/client/ui-trajectory/src/client/index.ts index 8c8ebc330d..b65eb3d3ab 100644 --- a/packages/client/ui-trajectory/src/client/index.ts +++ b/packages/client/ui-trajectory/src/client/index.ts @@ -9,8 +9,10 @@ import { TrajectoryStatsHeader, type TrajectoryChromeProps } from './TrajectoryS import { TrajectoryView } from './TrajectoryView.tsx' import { WaterfallView, type WaterfallExtraProps } from './WaterfallView.tsx' -export type { TrajectoryChromeProps } from './TrajectoryStatsHeader.tsx' -export type { WaterfallExtraProps } from './WaterfallView.tsx' +export { deriveSpans, deriveSpanStats, type SpanStats, type TurnSpan } from './spans.ts' +export { TrajectoryStatsHeader, type TrajectoryChromeProps } from './TrajectoryStatsHeader.tsx' +export { TrajectoryView } from './TrajectoryView.tsx' +export { WaterfallView, type WaterfallExtraProps } from './WaterfallView.tsx' declare module '@deepseek-ai/dsh-client-ui-conversation/client' { interface ConversationViewMap { diff --git a/packages/client/ui-trajectory/tests/views.spec.tsx b/packages/client/ui-trajectory/tests/views.spec.tsx index a49f77baf2..41a3c0c95b 100644 --- a/packages/client/ui-trajectory/tests/views.spec.tsx +++ b/packages/client/ui-trajectory/tests/views.spec.tsx @@ -13,14 +13,11 @@ import { createElement, Fragment, type FC, type ReactNode } from 'react' import { bindSnapshotSelector, createSnapshotStore } from '@deepseek-ai/dsh-client-web-react' import type { UseSession } from '@deepseek-ai/dsh-client-web-react' import type { ConversationSnapshot, SessionId, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client' -import { ConversationService } from '@deepseek-ai/dsh-client-ui-conversation/client' -import { ConversationRoot } from '@deepseek-ai/dsh-client-ui-conversation/src/client/skeleton/ConversationRoot.tsx' +import { ConversationRoot, ConversationService } from '@deepseek-ai/dsh-client-ui-conversation/client' import type { ConvViewProps, ViewEntry, ViewId } from '@deepseek-ai/dsh-client-ui-conversation/client' -import { apply, inject } from '@deepseek-ai/dsh-client-ui-trajectory/client' -import { deriveSpans, deriveSpanStats } from '@deepseek-ai/dsh-client-ui-trajectory/src/client/spans.ts' -import { TrajectoryStatsHeader } from '@deepseek-ai/dsh-client-ui-trajectory/src/client/TrajectoryStatsHeader.tsx' -import { TrajectoryView } from '@deepseek-ai/dsh-client-ui-trajectory/src/client/TrajectoryView.tsx' -import { WaterfallView } from '@deepseek-ai/dsh-client-ui-trajectory/src/client/WaterfallView.tsx' +import { + apply, deriveSpans, deriveSpanStats, inject, TrajectoryStatsHeader, TrajectoryView, WaterfallView, +} from '@deepseek-ai/dsh-client-ui-trajectory/client' import { apply as nodeApply } from '@deepseek-ai/dsh-client-ui-trajectory' const SID = 's1' as SessionId