fix: @-reference button no-ops — read conversation via ctx.get, not the ctx property
Cordis only grants property reads for services declared in the plugin's
inject list; every other read throws "cannot get property X without
inject" (the app's own plugins read 'conversation' through ctx.get for
this reason). referenceInChat now resolves the conversation service lazily
via ctx.get('conversation') and no-ops when absent. Verified end-to-end in
headless Chrome: clicking the @file button on root/dir/file rows now
appends the at-relative-path mention to the composer draft with no
console errors.
This commit is contained in:
+10
-7
@@ -13,7 +13,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useSyncExternalStore } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { IconChevronRightOutline14, IconFullscreenOutline16, IconPanelLeftOutline16, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { Context } from '../context-types.ts'
|
||||
import type { Context, SidebarConversation } from '../context-types.ts'
|
||||
import {
|
||||
allLeaves, closeTab, leafWithTab, mapLeaf, moveTab, moveTabToEdge, openTab,
|
||||
resizeSplit, sidebarStore, setWidth, toggleExpanded, togglePanel,
|
||||
@@ -187,18 +187,21 @@ export function Sidebar(props: { ctx: Context }) {
|
||||
|
||||
/**
|
||||
* The explorer's @-reference button: append `@<relative path>` to the
|
||||
* session's composer draft (space-separated). Resolves the session-scope
|
||||
* ctx and the conversation input service at click time; a missing service
|
||||
* or scope degrades to a logged no-op, never a crash. Defined above the
|
||||
* no-session early return — a hook must never sit behind a conditional
|
||||
* return (React counts hooks per render).
|
||||
* session's composer draft (space-separated). The conversation service is
|
||||
* resolved lazily through `ctx.get` (the inject-free read — the app's own
|
||||
* plugins read 'conversation' the same way); a missing service or scope
|
||||
* degrades to a logged no-op, never a crash. Defined above the no-session
|
||||
* early return — a hook must never sit behind a conditional return
|
||||
* (React counts hooks per render).
|
||||
*/
|
||||
const referenceInChat = useCallback((path: string): void => {
|
||||
if (sessionId === undefined) return
|
||||
try {
|
||||
const actx = ctx.sessions.scope(sessionId)
|
||||
if (actx === undefined) return
|
||||
const input = ctx.conversation.input.for(actx)
|
||||
const conversation = ctx.get('conversation') as SidebarConversation | undefined
|
||||
if (conversation === undefined) return
|
||||
const input = conversation.input.for(actx)
|
||||
const mention = `@${relativeTo(cwd ?? '', path)}`
|
||||
const draft = input.state.getSnapshot().draft
|
||||
input.setDraft(draft.trim() === '' ? mention : `${draft} ${mention}`)
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
* - httpServer: @deepseek-ai/dsh-host-webserver
|
||||
* - sessions: host side @deepseek-ai/dsh-session (SessionStore), client
|
||||
* side the runtime ISessions list feed
|
||||
* - conversation: client side ui-conversation's IConversation (composer draft)
|
||||
* - conversation: client side ui-conversation's IConversation (composer
|
||||
* draft), read lazily through `ctx.get` — cross-plugin service reads need
|
||||
* an inject declaration, so the direct property is never typed here
|
||||
* - loader: @cordisjs/plugin-loader (entry options)
|
||||
* - slots: the client runtime SlotsService
|
||||
* - effect: the DSH-vendored cordis lifecycle helper
|
||||
@@ -116,7 +118,7 @@ export interface SidebarSessionInput {
|
||||
setDraft(text: string): void
|
||||
}
|
||||
|
||||
/** The conversation service face (mirror of ui-conversation's IConversation). */
|
||||
/** The composer draft face the sidebar reaches through `ctx.get('conversation')`. */
|
||||
export interface SidebarConversation {
|
||||
input: {
|
||||
for(actx: Context): SidebarSessionInput
|
||||
@@ -127,7 +129,6 @@ declare module 'cordis' {
|
||||
interface Context {
|
||||
httpServer: SidebarHttpServer
|
||||
sessions: SidebarSessionStore & SidebarSessionsService
|
||||
conversation: SidebarConversation
|
||||
loader: SidebarLoader
|
||||
slots: SidebarSlotsService
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user