refactor(client): remove compatibility imports
This commit is contained in:
parent
3d1c0af60b
commit
997ad27a60
17 changed files with 57 additions and 60 deletions
|
|
@ -76,7 +76,10 @@ export interface ISessions {
|
|||
noteAgentPreset(sessionId: SessionId, agentPreset: string): void
|
||||
/** Clear the current selection into the no-session view state. */
|
||||
clear(): void
|
||||
/** @returns completion of the current or newly started Session-list refresh. */
|
||||
/**
|
||||
* Refresh the Host-authoritative Session list.
|
||||
* @returns completion of the current or newly started Session-list refresh.
|
||||
*/
|
||||
refresh(): Promise<void>
|
||||
/**
|
||||
* Search the Host's visible message-content index. Results stay
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import type {} from '@deepseek-ai/dsh-agent/types'
|
|||
import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { createSessionControlStream } from './transport.ts'
|
||||
import { ClientSessions } from './sessions/service.ts'
|
||||
import type { ISessions } from './contract/sessions.ts'
|
||||
import type { SessionRemotes } from './sessions/remotes.ts'
|
||||
import type {} from '../remote-events.ts'
|
||||
|
||||
|
|
@ -26,7 +25,7 @@ export type {
|
|||
} from './transport.ts'
|
||||
export { createScope, scopeOf } from './scope.ts'
|
||||
export type { AgentContext, AgentScopeHandle } from './scope.ts'
|
||||
export { SessionCreateError, SessionForkError, workspaceTitleOf } from './sessions/service.ts'
|
||||
export { SessionCreateError, SessionForkError } from './sessions/service.ts'
|
||||
export type { SessionBinding, SessionListState, SessionSummary } from './sessions/service.ts'
|
||||
export type {
|
||||
SessionListPhase,
|
||||
|
|
@ -52,18 +51,8 @@ export type {
|
|||
SessionSnapshot,
|
||||
} from './contract/snapshot.ts'
|
||||
export type { ClientFailure, ClientResult } from './contract/result.ts'
|
||||
export { indexSubagentDescendants } from './sessions/subagent-lineage.ts'
|
||||
export type { SubagentDescendantSummary } from './sessions/subagent-lineage.ts'
|
||||
|
||||
declare module '@deepseek-ai/cordis' {
|
||||
interface Events {
|
||||
/**
|
||||
* A Host connection generation completed its readiness handshake.
|
||||
* @mode emit
|
||||
*/
|
||||
'connection/reset'(): void
|
||||
}
|
||||
|
||||
interface Context {
|
||||
/** Client Session object layer and Agent scope owner. */
|
||||
sessions: import('./contract/sessions.ts').ISessions
|
||||
|
|
@ -79,17 +68,6 @@ export const inject = [
|
|||
'remote.session',
|
||||
]
|
||||
|
||||
/**
|
||||
* Resolve the Client Session service from any Client Cordis context.
|
||||
* @param ctx - Client root or Agent-scoped context.
|
||||
* @returns the Client Session object layer.
|
||||
*/
|
||||
export function resolveClientSessions(ctx: Context): ISessions {
|
||||
const sessions = ctx.get('sessions')
|
||||
if (sessions === undefined) throw new Error('session-controller: Client sessions service unavailable')
|
||||
return sessions
|
||||
}
|
||||
|
||||
/**
|
||||
* Install Client Session state and its reconnecting control stream.
|
||||
* @param ctx - Client Cordis context.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ async function mount(initialHost?: HostDescription): Promise<Bench> {
|
|||
ctx.reflect.provide('remote.session', remote.session)
|
||||
const fiber = ctx.plugin(SessionClient)
|
||||
await fiber
|
||||
const sessions = SessionClient.resolveClientSessions(ctx) as ClientSessions
|
||||
const sessions = ctx.sessions as ClientSessions
|
||||
return {
|
||||
ctx,
|
||||
api,
|
||||
|
|
@ -108,14 +108,6 @@ async function flush(): Promise<void> {
|
|||
}
|
||||
|
||||
describe('Session Controller Client apply', () => {
|
||||
it('requires the installed Session service at the resolver boundary', () => {
|
||||
const ctx = new Context()
|
||||
contexts.add(ctx)
|
||||
|
||||
expect(() => SessionClient.resolveClientSessions(ctx))
|
||||
.toThrow('session-controller: Client sessions service unavailable')
|
||||
})
|
||||
|
||||
it('routes Session Remote Events and connection generations into the object layer', async () => {
|
||||
const connected = vi.spyOn(ClientSessions.prototype, 'handleConnected')
|
||||
const error = vi.spyOn(ClientSessions.prototype, 'handleSessionError')
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
import { Service, type Context } from '@deepseek-ai/cordis'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { RemoteFailure } from '@deepseek-ai/dsh-typert-protocol'
|
||||
import type { WorkspaceId, WorkspaceView } from '../types.ts'
|
||||
import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types'
|
||||
import type { WorkspaceView } from '../types.ts'
|
||||
import type { ClientWorkspaceModel, WorkspaceSnapshot } from './model.ts'
|
||||
|
||||
/** Structured create failure for callers that distinguish Host business errors. */
|
||||
|
|
|
|||
|
|
@ -133,13 +133,29 @@ export interface InputTriggerController {
|
|||
|
||||
declare module '@deepseek-ai/cordis' {
|
||||
interface Events {
|
||||
/** @param request - command claim and span. @mode bail */
|
||||
/**
|
||||
* Claim a command token for the scoped input machine.
|
||||
* @param request - command claim and span.
|
||||
* @mode bail
|
||||
*/
|
||||
'slash/input-begin-command'(request: BeginCommandRequest): true | undefined
|
||||
/** @param request - reference and span. @mode bail */
|
||||
/**
|
||||
* Insert a structured reference into the scoped input machine.
|
||||
* @param request - reference and span.
|
||||
* @mode bail
|
||||
*/
|
||||
'slash/input-insert-reference'(request: InsertReferenceRequest): true | undefined
|
||||
/** @param request - token guard. @mode bail */
|
||||
/**
|
||||
* Consume a trigger token without inserting replacement content.
|
||||
* @param request - token guard.
|
||||
* @mode bail
|
||||
*/
|
||||
'slash/input-consume-token'(request: ConsumeTokenRequest): true | undefined
|
||||
/** @param request - plain text and span. @mode bail */
|
||||
/**
|
||||
* Insert plain text into the scoped input machine.
|
||||
* @param request - plain text and span.
|
||||
* @mode bail
|
||||
*/
|
||||
'slash/input-insert-text'(request: InsertTextRequest): true | undefined
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } fr
|
|||
import type { ChangeEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {
|
||||
IconPlusOutline16, IconWarningOutline16, Toast, Tooltip,
|
||||
IconPlusOutline16, IconWarningOutline16, ReferenceIcon, Toast, Tooltip,
|
||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
// Type-only: the `plan` projection key merge (the TodoDock posture — the
|
||||
// composer reads a host-computed value; the domain owns the key).
|
||||
|
|
@ -24,7 +24,6 @@ import { deriveDecorations } from './decorations.ts'
|
|||
import type { DraftDecorations } from './decorations.ts'
|
||||
import type { EditRange } from '../contract/input.ts'
|
||||
import { attachmentErrorText, imageSizeText } from '../image-labels.ts'
|
||||
import { ReferenceIcon } from './ReferenceIcon.tsx'
|
||||
import { ContextMeter } from './ContextMeter.tsx'
|
||||
import { PermissionSelect } from './PermissionSelect.tsx'
|
||||
import { isSafariBrowser, repairSafariTextareaLayout } from './safari.ts'
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@
|
|||
*/
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'
|
||||
import type {
|
||||
ArbitrateKey, ArbitrateOutcome, PickOutcome,
|
||||
} from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import { detectTrigger } from '../core/detect.ts'
|
||||
import { MENU_CLOSED, menuReduce, seedGroups } from '../core/menu.ts'
|
||||
import type { MenuEvent, MenuState, TriggerHit } from '../core/contract.ts'
|
||||
import type {
|
||||
ArbitrateKey, ArbitrateOutcome, ClientSessionContext, PickOutcome, InputTriggerSource, SubmitEnvelope, TriggerChar, TriggerGuard,
|
||||
ClientSessionContext, InputTriggerSource, SubmitEnvelope, TriggerChar, TriggerGuard,
|
||||
} from '../types.ts'
|
||||
|
||||
/** Roster access the controller borrows from the root service (registration order preserved). */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
// Type-only: pulls the locale plugin's Context merge (ctx.locale).
|
||||
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import { resolveClientSessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type {} from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-session/client'
|
||||
import { InputTriggerService } from './service.ts'
|
||||
|
|
@ -60,7 +60,7 @@ export function apply(ctx: ClientContext): void {
|
|||
ctx.effect(() => ctx.locale.register(MENU_NS, { zh, en }), 'ui-input-trigger: menu dictionaries')
|
||||
ctx.inject(['slots', 'inputTriggers', 'sessions'], (scope: ClientContext) => {
|
||||
const inputTriggers = scope.inputTriggers
|
||||
const sessions = resolveClientSessions(scope)
|
||||
const sessions = scope.sessions
|
||||
scope.slots.inject('conversation.input.overlay', () => scope.slots.register({
|
||||
name: 'conversation.input.overlay',
|
||||
id: 'slash-menu',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
* live in sibling modules annotated with these
|
||||
* aliases; the service shell wires them to ctx.
|
||||
*/
|
||||
import type { InputTriggerCandidate, TokenSpan, TriggerChar, TriggerGuard, TriggerPosition } from '../types.ts'
|
||||
import type { TokenSpan } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type { InputTriggerCandidate, TriggerChar, TriggerGuard, TriggerPosition } from '../types.ts'
|
||||
|
||||
/** A detected trigger token under the caret. */
|
||||
export interface TriggerHit {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@
|
|||
import { Context } from '@deepseek-ai/cordis'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'
|
||||
import {
|
||||
createScope, resolveClientSessions, scopeOf,
|
||||
} from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import { createScope, scopeOf } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import { SlotRegistry } from '@deepseek-ai/dsh-client-ui-renderer/client'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import { apply, inject, InputTriggerService } from '@deepseek-ai/dsh-client-ui-input-trigger/client'
|
||||
|
|
@ -80,7 +78,7 @@ describe('apply', () => {
|
|||
const injectEntry = entries[0]!.inject as unknown as (sessionId: SessionId) => MenuViewInjected
|
||||
const injected = injectEntry(sid('a'))
|
||||
const controller = inputTriggers.sessionOf(
|
||||
resolveClientSessions(ctx).scope(sid('a'))!,
|
||||
ctx.sessions.scope(sid('a'))!,
|
||||
)
|
||||
expect(injected.menu).toBe(controller.menu)
|
||||
// The pick face routes into the controller pipeline (closed menu → no-op).
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
// Type-only: the carrier types, the forwarded Host-event face and the ctx.remote merge.
|
||||
import type { ModelSelection, SessionModels } from '@deepseek-ai/dsh-api-session-controller/types'
|
||||
import { resolveClientSessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type {} from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type { CommandUiContract, SelectOption } from '@deepseek-ai/dsh-client-ui-commands/client'
|
||||
// Type-only: pulls the ui-conversation SlotMap merge (the input.model seat).
|
||||
|
|
@ -125,7 +125,7 @@ export function apply(ctx: ClientContext): void {
|
|||
ctx.inject(['commandUi', 'modelDirectories'], (scope: ClientContext) => {
|
||||
const command = scope.get('commandUi') as CommandUiContract
|
||||
const models = scope.modelDirectories
|
||||
const sessions = resolveClientSessions(scope)
|
||||
const sessions = scope.sessions
|
||||
scope.effect(() => command.register({
|
||||
name: 'model',
|
||||
description: t('command.description'),
|
||||
|
|
@ -156,7 +156,7 @@ export function apply(ctx: ClientContext): void {
|
|||
// Entry 2: the composer's named model seat over the SAME directory.
|
||||
ctx.inject(['slots', 'modelDirectories'], (scope: ClientContext) => {
|
||||
const models = scope.modelDirectories
|
||||
const sessions = resolveClientSessions(scope)
|
||||
const sessions = scope.sessions
|
||||
scope.slots.inject('conversation.input.model', () => scope.slots.register({
|
||||
name: 'conversation.input.model',
|
||||
locale: NS,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
import { Service } from '@deepseek-ai/cordis'
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import { resolveClientSessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type {} from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import { ModelDirectory } from './directory.ts'
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ export class ModelDirectoryResolver extends Service {
|
|||
const { live } = this
|
||||
const existing = live.directories.get(sessionId)
|
||||
if (existing !== undefined) return existing
|
||||
const sessions = resolveClientSessions(this.ctx)
|
||||
const sessions = this.ctx.sessions
|
||||
const actx = sessions.scope(sessionId)
|
||||
if (actx === undefined) throw new Error(`ui-model-selection: session "${String(sessionId)}" resolved no scope`)
|
||||
const directory = new ModelDirectory(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'
|
||||
import { resolveClientSessions, type SessionFace } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { SessionFace } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
// Type-only: pulls the locale plugin's Context merge (ctx.locale).
|
||||
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
||||
// Type-only: the settings slot types (this package registers a General row).
|
||||
|
|
@ -83,7 +83,7 @@ function optionsOf(value: PermissionSelect, t: (key: string) => string): SelectO
|
|||
*/
|
||||
export function apply(ctx: ClientContext): void {
|
||||
const command = ctx.get('commandUi') as CommandUiContract
|
||||
const sessions = resolveClientSessions(ctx)
|
||||
const sessions = ctx.sessions
|
||||
// This optional bundle and ui-conversation can load independently, so each
|
||||
// owns the same safety copy under its own locale namespace.
|
||||
/* jscpd:ignore-start */
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
// Type-only: the carrier types, the forwarded Host-event face and the ctx.remote merge.
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type { ConnectionHandle, SkillEntry } from '@deepseek-ai/dsh-api-remotes/client'
|
||||
import { resolveClientSessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type {} from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { InputTriggerServiceContract, InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'
|
||||
// Type-only: pulls the locale plugin's Context merge (ctx.locale).
|
||||
|
|
@ -72,7 +72,7 @@ export function apply(ctx: ClientContext): void {
|
|||
))
|
||||
|
||||
const skills = (ctx.get('connection') as ConnectionHandle).api.skills
|
||||
const sessions = resolveClientSessions(ctx)
|
||||
const sessions = ctx.sessions
|
||||
// Session-keyed catalog cache; single-flight per key. Plugin-closure state:
|
||||
// the fiber effect below is its teardown boundary.
|
||||
const fetches = new Map<SessionId, CatalogFetch>()
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* consumer merges keys in and the intersection is what keeps them string-typed.
|
||||
* The rule fires on the empty-map view, not on real redundancy. */
|
||||
import type { ReactNode } from 'react'
|
||||
import type {
|
||||
BoundActions, HandleOf, PropsStore, SnapshotSelectorHook, StoreDecl,
|
||||
} from '@deepseek-ai/dsh-client-store'
|
||||
import type { HostObservable } from './renderer.ts'
|
||||
import type { BoundActions, HandleOf, PropsStore, SnapshotSelectorHook, StoreDecl } from './store.ts'
|
||||
|
||||
export * from './store.ts'
|
||||
export * from './renderer.ts'
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-api-remotes/client'
|
||||
import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { ComposerChainProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
||||
import type { PendingInteractionPublisher } from '@deepseek-ai/dsh-client-ui-session/client'
|
||||
|
|
@ -56,7 +57,7 @@ async function answerQuestion(
|
|||
next: ClientQuestionNext,
|
||||
registerPendingInteraction: PendingInteractionPublisher<PendingQuestion>,
|
||||
): Promise<ClientQuestionAnswer> {
|
||||
const sessionId = ctx.sessions.scopeOf(owner)
|
||||
const sessionId = (ctx.sessions as ISessions).scopeOf(owner)
|
||||
if (sessionId === undefined) return next()
|
||||
const pending = new PendingQuestion(sessionId, request.questions, request.signal)
|
||||
const completed = Promise.withResolvers<void>()
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ export interface UiWorkspace {
|
|||
* @param sessionId - Session to archive.
|
||||
*/
|
||||
archiveSession(sessionId: SessionId): Promise<void>
|
||||
/** @returns the Host-native picked directory, or null when cancelled. */
|
||||
/**
|
||||
* Open the Host-native directory picker.
|
||||
* @returns the selected directory, or null when cancelled.
|
||||
*/
|
||||
pickDirectory(): Promise<string | null>
|
||||
/**
|
||||
* List one Host directory level.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue