/** * Interception of the chat's produced-files row: the turn-tail chain entry * that replaces ui-deliverables' row when the closing turn produced files. * The takeover looks identical (same chip row); the chips open the file in * the sidebar instead of the host OS. Priority -1 runs before the default-0 * deliverables entry; when nothing was produced the selector returns null * and the original row renders unchanged. */ import { IconCodeOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import type { Context } from '../context-types.ts' import { openTab } from './state.ts' import { sidebarStore } from './state.ts' import { t } from './locales.ts' import { resolveSidebarPath, selectProducedFiles } from './produced-files.ts' import css from './sidebar.module.css' /** Open a file in the sidebar's editor (used by the intercepted row and the explorer). */ export function openSidebarFile(ctx: Context, sessionId: string, path: string): void { const summary = ctx.sessions.list.getSnapshot().byId[sessionId] const absolute = resolveSidebarPath(summary?.cwd, path) const at = Math.max(absolute.lastIndexOf('/'), absolute.lastIndexOf('\\')) const title = at === -1 ? absolute : absolute.slice(at + 1) sidebarStore.reduce(state => openTab(state, { id: `editor:${absolute}`, type: 'editor', title, path: absolute, })) } /** The intercepted produced-files row (visual twin of the deliverables chips). */ export function SidebarProducedFiles(props: { matched: readonly string[] openInSidebar: (path: string) => void }) { const { matched, openInSidebar } = props const shown = matched.slice(0, 6) const hidden = matched.length - shown.length return (