Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4c44d13d6 |
No files matched your search
+22
-22
@@ -155,29 +155,29 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cordisjs/plugin-loader": "^1.0.0-rc.5",
|
"@cordisjs/plugin-loader": "^1.0.0-rc.5",
|
||||||
"@deepseek-ai/dsh-agent": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-agent": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-agent-loop": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-agent-loop": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-attachment": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-ui-conversation": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-code-runtime": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-code-runtime": "0.1.5-rc.2",
|
||||||
"@deepseek-ai/dsh-host-webserver": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-host-webserver": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-llm": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-llm": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-scope": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-scope": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-session": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-session": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-session-persistence": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-session-projection": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-session-projection": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-settings": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-settings": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-subagent": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-subagent": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-tools": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-user-approval": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-user-approval": "0.2.0-rc.2",
|
||||||
"@deepseek-ai/dsh-util-time": "0.1.5-rc.2",
|
"@deepseek-ai/dsh-util-time": "0.2.0-rc.2",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@huanlin/dsh-plugin-better-locale": "^0.1.0",
|
"@huanlin/dsh-plugin-better-locale": "^0.1.0",
|
||||||
"@playwright/test": "^1.62.1",
|
"@playwright/test": "^1.62.1",
|
||||||
|
|||||||
Generated
+761
-379
File diff suppressed because it is too large.
Load diff
+10
-10
@@ -18,11 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
IconChevronLeftOutline14,
|
IconChevronLeftOutlineRegular,
|
||||||
IconChevronRightOutline14,
|
IconChevronRightOutlineRegular,
|
||||||
IconLinkOutline14,
|
IconLinkOutlineRegular,
|
||||||
IconRefreshOutline14,
|
IconRefreshOutlineRegular,
|
||||||
IconWarningOutline16,
|
IconWarningOutlineMedium,
|
||||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { VscLinkExternal } from 'react-icons/vsc'
|
import { VscLinkExternal } from 'react-icons/vsc'
|
||||||
import { api } from './api.ts'
|
import { api } from './api.ts'
|
||||||
@@ -172,7 +172,7 @@ export function BrowserView(props: TabComponentProps) {
|
|||||||
disabled={cursor <= 0}
|
disabled={cursor <= 0}
|
||||||
onClick={goBack}
|
onClick={goBack}
|
||||||
>
|
>
|
||||||
<IconChevronLeftOutline14 />
|
<IconChevronLeftOutlineRegular />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -182,7 +182,7 @@ export function BrowserView(props: TabComponentProps) {
|
|||||||
disabled={cursor >= history.length - 1}
|
disabled={cursor >= history.length - 1}
|
||||||
onClick={goForward}
|
onClick={goForward}
|
||||||
>
|
>
|
||||||
<IconChevronRightOutline14 />
|
<IconChevronRightOutlineRegular />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -191,7 +191,7 @@ export function BrowserView(props: TabComponentProps) {
|
|||||||
title={t('refresh')}
|
title={t('refresh')}
|
||||||
onClick={() => { setReloadKey(key => key + 1) }}
|
onClick={() => { setReloadKey(key => key + 1) }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline14 />
|
<IconRefreshOutlineRegular />
|
||||||
</button>
|
</button>
|
||||||
<input
|
<input
|
||||||
className={css.browserInput}
|
className={css.browserInput}
|
||||||
@@ -210,7 +210,7 @@ export function BrowserView(props: TabComponentProps) {
|
|||||||
title={t('browserGo')}
|
title={t('browserGo')}
|
||||||
onClick={() => { navigateTo(input) }}
|
onClick={() => { navigateTo(input) }}
|
||||||
>
|
>
|
||||||
<IconLinkOutline14 />
|
<IconLinkOutlineRegular />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -273,7 +273,7 @@ export function BrowserEmbedBlocked(props: {
|
|||||||
try { host = new URL(url).hostname } catch { /* keep the raw URL */ }
|
try { host = new URL(url).hostname } catch { /* keep the raw URL */ }
|
||||||
return (
|
return (
|
||||||
<div className={css.browserBlocked}>
|
<div className={css.browserBlocked}>
|
||||||
<IconWarningOutline16 size={16} />
|
<IconWarningOutlineMedium size={16} />
|
||||||
<div className={css.browserBlockedTitle}>{t('browserEmbedBlocked', { host })}</div>
|
<div className={css.browserBlockedTitle}>{t('browserEmbedBlocked', { host })}</div>
|
||||||
<div className={css.browserBlockedDesc}>{t('browserEmbedBlockedDesc')}</div>
|
<div className={css.browserBlockedDesc}>{t('browserEmbedBlockedDesc')}</div>
|
||||||
<div className={css.browserBlockedActions}>
|
<div className={css.browserBlockedActions}>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* renderer — the same one the changes tab's inline preview uses.
|
* renderer — the same one the changes tab's inline preview uses.
|
||||||
*/
|
*/
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconRefreshOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { SessionScope } from './api.ts'
|
import type { SessionScope } from './api.ts'
|
||||||
import { api } from './api.ts'
|
import { api } from './api.ts'
|
||||||
import type { SidebarDiffRef } from './state.ts'
|
import type { SidebarDiffRef } from './state.ts'
|
||||||
@@ -170,7 +170,7 @@ export function DiffTab(props: { sessionId: string; cwd: string | undefined; dif
|
|||||||
title={t('refresh')}
|
title={t('refresh')}
|
||||||
onClick={refresh}
|
onClick={refresh}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline16 size={14} />
|
<IconRefreshOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{loading && <div className={css.gitPlaceholder}>{t('loading')}</div>}
|
{loading && <div className={css.gitPlaceholder}>{t('loading')}</div>}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'
|
||||||
import { createElement } from 'react'
|
import { createElement } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { IconCheckOutline16, IconFolderOpen16, IconRefreshOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCheckOutlineMedium, IconFolderOpenMedium, IconRefreshOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { Context } from '../context-types.ts'
|
import type { Context } from '../context-types.ts'
|
||||||
import { api, isOutsideWorkspaceMessage, mediaUrl, type SessionScope } from './api.ts'
|
import { api, isOutsideWorkspaceMessage, mediaUrl, type SessionScope } from './api.ts'
|
||||||
import { BinaryDownload } from './binary-download.tsx'
|
import { BinaryDownload } from './binary-download.tsx'
|
||||||
@@ -447,7 +447,7 @@ export function EditorHost(props: {
|
|||||||
title={`${t('save')} (Ctrl/Cmd+S)`}
|
title={`${t('save')} (Ctrl/Cmd+S)`}
|
||||||
onClick={() => { controlsRef.current?.save() }}
|
onClick={() => { controlsRef.current?.save() }}
|
||||||
>
|
>
|
||||||
<IconCheckOutline16 size={14} />
|
<IconCheckOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{saveLabel !== '' && (
|
{saveLabel !== '' && (
|
||||||
@@ -461,7 +461,7 @@ export function EditorHost(props: {
|
|||||||
title={t('refresh')}
|
title={t('refresh')}
|
||||||
onClick={refreshFile}
|
onClick={refreshFile}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline14 size={14} />
|
<IconRefreshOutlineRegular size={14} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
@@ -472,7 +472,7 @@ export function EditorHost(props: {
|
|||||||
aria-pressed={treeOpen}
|
aria-pressed={treeOpen}
|
||||||
onClick={toggleTree}
|
onClick={toggleTree}
|
||||||
>
|
>
|
||||||
<IconFolderOpen16 size={14} />
|
<IconFolderOpenMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={css.editorBody}>
|
<div className={css.editorBody}>
|
||||||
|
|||||||
+13
-13
@@ -24,8 +24,8 @@ import { useCallback, useEffect, useMemo, useRef, useState, type DragEvent, type
|
|||||||
import { createPortal } from 'react-dom'
|
import { createPortal } from 'react-dom'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import {
|
import {
|
||||||
Button, IconChevronRightOutline14, IconCloseFill14, IconCodeOutline16, IconCopyOutline16, IconDownloadOutline16,
|
Button, IconChevronRightOutlineRegular, IconCloseFillRegular, IconCodeOutlineMedium, IconCopyOutlineMedium, IconDownloadOutlineMedium,
|
||||||
IconEditOutline16, IconLinkOutline16, IconTrashOutline16, Menu, Modal, type MenuEntry, type MenuItem, writeClipboard,
|
IconEditOutlineMedium, IconLinkOutlineMedium, IconTrashOutlineMedium, Menu, Modal, type MenuEntry, type MenuItem, writeClipboard,
|
||||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { SiCursor, SiZedindustries } from 'react-icons/si'
|
import { SiCursor, SiZedindustries } from 'react-icons/si'
|
||||||
import { VscFolderOpened, VscLinkExternal, VscPin, VscPinned } from 'react-icons/vsc'
|
import { VscFolderOpened, VscLinkExternal, VscPin, VscPinned } from 'react-icons/vsc'
|
||||||
@@ -486,7 +486,7 @@ export function FileTree(props: {
|
|||||||
if (target.id === 'vscode') return <IconVscode16 size={14} />
|
if (target.id === 'vscode') return <IconVscode16 size={14} />
|
||||||
if (target.id === 'cursor') return <SiCursor size={14} />
|
if (target.id === 'cursor') return <SiCursor size={14} />
|
||||||
if (target.id === 'zed') return <SiZedindustries size={14} />
|
if (target.id === 'zed') return <SiZedindustries size={14} />
|
||||||
return <IconCodeOutline16 size={14} />
|
return <IconCodeOutlineMedium size={14} />
|
||||||
}
|
}
|
||||||
const pinned = openWithTargets
|
const pinned = openWithTargets
|
||||||
.filter(target => pinnedIds.includes(target.id))
|
.filter(target => pinnedIds.includes(target.id))
|
||||||
@@ -537,7 +537,7 @@ export function FileTree(props: {
|
|||||||
label: (
|
label: (
|
||||||
<span className={css.openWithLabel}>
|
<span className={css.openWithLabel}>
|
||||||
<span className={css.openWithName}>{t('openWithMenu')}</span>
|
<span className={css.openWithName}>{t('openWithMenu')}</span>
|
||||||
<IconChevronRightOutline14 size={14} className={css.openWithChevron} aria-hidden />
|
<IconChevronRightOutlineRegular size={14} className={css.openWithChevron} aria-hidden />
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
icon: <VscLinkExternal size={14} />,
|
icon: <VscLinkExternal size={14} />,
|
||||||
@@ -661,7 +661,7 @@ export function FileTree(props: {
|
|||||||
>
|
>
|
||||||
{dirRowIcon(entry.path, isOpen)}
|
{dirRowIcon(entry.path, isOpen)}
|
||||||
<span className={css.explorerName}>{entry.name}</span>
|
<span className={css.explorerName}>{entry.name}</span>
|
||||||
{entry.isSymlink && <IconLinkOutline16 size={12} className={css.explorerSymlink} />}
|
{entry.isSymlink && <IconLinkOutlineMedium size={12} className={css.explorerSymlink} />}
|
||||||
{rowActions(entry)}
|
{rowActions(entry)}
|
||||||
</div>
|
</div>
|
||||||
{isOpen && renderLevel(entry.path, depth + 1)}
|
{isOpen && renderLevel(entry.path, depth + 1)}
|
||||||
@@ -694,7 +694,7 @@ export function FileTree(props: {
|
|||||||
>
|
>
|
||||||
{fileRowIcon(entry.path)}
|
{fileRowIcon(entry.path)}
|
||||||
<span className={css.explorerName}>{entry.name}</span>
|
<span className={css.explorerName}>{entry.name}</span>
|
||||||
{entry.isSymlink && <IconLinkOutline16 size={12} className={css.explorerSymlink} />}
|
{entry.isSymlink && <IconLinkOutlineMedium size={12} className={css.explorerSymlink} />}
|
||||||
{rowActions(entry)}
|
{rowActions(entry)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -726,7 +726,7 @@ export function FileTree(props: {
|
|||||||
aria-label={t('dismiss')}
|
aria-label={t('dismiss')}
|
||||||
onClick={() => { setActionError(null) }}
|
onClick={() => { setActionError(null) }}
|
||||||
>
|
>
|
||||||
<IconCloseFill14 />
|
<IconCloseFillRegular />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -829,7 +829,7 @@ export function FileTree(props: {
|
|||||||
items={[
|
items={[
|
||||||
// The open escapes head the FILE menu (dirs only get copy).
|
// The open escapes head the FILE menu (dirs only get copy).
|
||||||
...(rowMenu?.isDir === false && onOpenFileNewTab !== undefined
|
...(rowMenu?.isDir === false && onOpenFileNewTab !== undefined
|
||||||
? [{ id: 'open-new-tab', label: t('openFileNewTab'), icon: <IconCodeOutline16 size={14} /> }]
|
? [{ id: 'open-new-tab', label: t('openFileNewTab'), icon: <IconCodeOutlineMedium size={14} /> }]
|
||||||
: []),
|
: []),
|
||||||
...(rowMenu?.isDir === false && onOpenFileSide !== undefined
|
...(rowMenu?.isDir === false && onOpenFileSide !== undefined
|
||||||
? [{ id: 'open-side', label: t('openFileSide'), icon: <VscFolderOpened size={14} /> }]
|
? [{ id: 'open-side', label: t('openFileSide'), icon: <VscFolderOpened size={14} /> }]
|
||||||
@@ -837,21 +837,21 @@ export function FileTree(props: {
|
|||||||
...openWithEntries(),
|
...openWithEntries(),
|
||||||
// Download applies to files only (the host route refuses directories).
|
// Download applies to files only (the host route refuses directories).
|
||||||
...(rowMenu?.isDir === false
|
...(rowMenu?.isDir === false
|
||||||
? [{ id: 'download', label: t('download'), icon: <IconDownloadOutline16 size={14} /> }]
|
? [{ id: 'download', label: t('download'), icon: <IconDownloadOutlineMedium size={14} /> }]
|
||||||
: []),
|
: []),
|
||||||
// Upload into a directory (incl. the workspace root row).
|
// Upload into a directory (incl. the workspace root row).
|
||||||
...(rowMenu?.isDir === true
|
...(rowMenu?.isDir === true
|
||||||
? [{ id: 'upload-here', label: t('uploadHere'), icon: <IconUploadOutline16 size={14} /> }]
|
? [{ id: 'upload-here', label: t('uploadHere'), icon: <IconUploadOutline16 size={14} /> }]
|
||||||
: []),
|
: []),
|
||||||
{ id: 'relative', label: t('copyRelative'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'relative', label: t('copyRelative'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
{ id: 'absolute', label: t('copyAbsolute'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'absolute', label: t('copyAbsolute'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
// Explorer mutations close the menu; the workspace ROOT row is the
|
// Explorer mutations close the menu; the workspace ROOT row is the
|
||||||
// session itself — never renamable or deletable (server double-guards).
|
// session itself — never renamable or deletable (server double-guards).
|
||||||
...(rowMenu !== null && rowMenu.path !== cwd
|
...(rowMenu !== null && rowMenu.path !== cwd
|
||||||
? [
|
? [
|
||||||
{ id: 'mutate-sep', type: 'separator' } as MenuEntry,
|
{ id: 'mutate-sep', type: 'separator' } as MenuEntry,
|
||||||
{ id: 'rename', label: t('rename'), icon: <IconEditOutline16 size={14} /> },
|
{ id: 'rename', label: t('rename'), icon: <IconEditOutlineMedium size={14} /> },
|
||||||
{ id: 'delete', label: t('delete'), icon: <IconTrashOutline16 size={14} />, danger: true },
|
{ id: 'delete', label: t('delete'), icon: <IconTrashOutlineMedium size={14} />, danger: true },
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -42,9 +42,9 @@
|
|||||||
*/
|
*/
|
||||||
import { Fragment, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
|
import { Fragment, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
|
||||||
import {
|
import {
|
||||||
IconChevronDownOutline14,
|
IconChevronDownOutlineRegular,
|
||||||
IconPlusOutline16,
|
IconPlusOutlineMedium,
|
||||||
IconSettingsOutline16,
|
IconSettingsOutlineMedium,
|
||||||
Input,
|
Input,
|
||||||
Menu,
|
Menu,
|
||||||
Modal,
|
Modal,
|
||||||
@@ -420,7 +420,7 @@ function SelectMenu(props: {
|
|||||||
<span className={css.selectAnchorText}>
|
<span className={css.selectAnchorText}>
|
||||||
{selected.length === 0 ? (placeholder ?? '—') : selected.map(option => textOf(option.title)).join(', ')}
|
{selected.length === 0 ? (placeholder ?? '—') : selected.map(option => textOf(option.title)).join(', ')}
|
||||||
</span>
|
</span>
|
||||||
<IconChevronDownOutline14 size={12} />
|
<IconChevronDownOutlineRegular size={12} />
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -817,7 +817,7 @@ export function SideCardSection({ store, service }: SideCardSectionProps) {
|
|||||||
aria-label={`${props.title} ${t('settingsPopup')}`}
|
aria-label={`${props.title} ${t('settingsPopup')}`}
|
||||||
onClick={props.onOpenSettings}
|
onClick={props.onOpenSettings}
|
||||||
>
|
>
|
||||||
<IconSettingsOutline16 size={12} />
|
<IconSettingsOutlineMedium size={12} />
|
||||||
<span>{t('settingsPopup')}</span>
|
<span>{t('settingsPopup')}</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@@ -893,7 +893,7 @@ export function SideCardSection({ store, service }: SideCardSectionProps) {
|
|||||||
title={t('settingsPopup')}
|
title={t('settingsPopup')}
|
||||||
onClick={() => { setStripSettingsOpen(true) }}
|
onClick={() => { setStripSettingsOpen(true) }}
|
||||||
>
|
>
|
||||||
<IconSettingsOutline16 size={14} />
|
<IconSettingsOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@@ -935,7 +935,7 @@ export function SideCardSection({ store, service }: SideCardSectionProps) {
|
|||||||
>
|
>
|
||||||
<span className={css.cardTop}>
|
<span className={css.cardTop}>
|
||||||
<span className={css.cardIconChip}>
|
<span className={css.cardIconChip}>
|
||||||
<IconPlusOutline16 size={16} />
|
<IconPlusOutlineMedium size={16} />
|
||||||
</span>
|
</span>
|
||||||
<span className={css.cardTitle}>{t('addPluginsTabCard')}</span>
|
<span className={css.cardTitle}>{t('addPluginsTabCard')}</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -974,7 +974,7 @@ export function SideCardSection({ store, service }: SideCardSectionProps) {
|
|||||||
>
|
>
|
||||||
<span className={css.cardTop}>
|
<span className={css.cardTop}>
|
||||||
<span className={css.cardIconChip}>
|
<span className={css.cardIconChip}>
|
||||||
<IconPlusOutline16 size={16} />
|
<IconPlusOutlineMedium size={16} />
|
||||||
</span>
|
</span>
|
||||||
<span className={css.cardTitle}>{t('addPluginsViewerCard')}</span>
|
<span className={css.cardTitle}>{t('addPluginsViewerCard')}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
+35
-23
@@ -29,16 +29,16 @@ import clsx from 'clsx'
|
|||||||
import {
|
import {
|
||||||
ConnectionIndicator,
|
ConnectionIndicator,
|
||||||
DiffBlock,
|
DiffBlock,
|
||||||
IconApiOutline14,
|
IconApiOutlineRegular,
|
||||||
IconBrowseOutline16,
|
IconBrowseOutlineMedium,
|
||||||
IconChevronRightOutline14,
|
IconChevronRightOutlineRegular,
|
||||||
IconEditOutline16,
|
IconEditOutlineMedium,
|
||||||
IconNewChatOutline16,
|
IconNewChatOutlineMedium,
|
||||||
IconPlusOutline16,
|
IconPlusOutlineMedium,
|
||||||
IconSearchOutline16,
|
IconSearchOutlineMedium,
|
||||||
IconSendOutline16,
|
IconSendOutlineMedium,
|
||||||
IconSparkle16,
|
IconSparkleMedium,
|
||||||
IconStopFill16,
|
IconStopFillMedium,
|
||||||
MarkdownText,
|
MarkdownText,
|
||||||
Menu,
|
Menu,
|
||||||
ReadBlock,
|
ReadBlock,
|
||||||
@@ -198,7 +198,7 @@ function CollapsibleRow(props: {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className={css.sidechatRowChevron}>
|
<span className={css.sidechatRowChevron}>
|
||||||
<IconChevronRightOutline14 size={12} />
|
<IconChevronRightOutlineRegular size={12} />
|
||||||
</span>
|
</span>
|
||||||
{leading}
|
{leading}
|
||||||
{label}
|
{label}
|
||||||
@@ -239,19 +239,19 @@ function toolLeading(name: string, failed: boolean): React.ReactNode {
|
|||||||
switch (name) {
|
switch (name) {
|
||||||
case 'bash':
|
case 'bash':
|
||||||
case 'pwsh':
|
case 'pwsh':
|
||||||
return <IconApiOutline14 size={14} />
|
return <IconApiOutlineRegular size={14} />
|
||||||
case 'read':
|
case 'read':
|
||||||
case 'web_fetch':
|
case 'web_fetch':
|
||||||
return <IconBrowseOutline16 size={14} />
|
return <IconBrowseOutlineMedium size={14} />
|
||||||
case 'edit':
|
case 'edit':
|
||||||
case 'write':
|
case 'write':
|
||||||
return <IconEditOutline16 size={14} />
|
return <IconEditOutlineMedium size={14} />
|
||||||
case 'grep':
|
case 'grep':
|
||||||
case 'glob':
|
case 'glob':
|
||||||
case 'web_search':
|
case 'web_search':
|
||||||
return <IconSearchOutline16 size={14} />
|
return <IconSearchOutlineMedium size={14} />
|
||||||
default:
|
default:
|
||||||
return <IconSparkle16 size={14} />
|
return <IconSparkleMedium size={14} />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,13 +354,26 @@ export function SideChatView(props: {
|
|||||||
...shared,
|
...shared,
|
||||||
signal: (signal: string) => t('sideChatBlockSignal', { signal }),
|
signal: (signal: string) => t('sideChatBlockSignal', { signal }),
|
||||||
exitCode: (exitCode: number) => t('sideChatBlockExitCode', { code: exitCode }),
|
exitCode: (exitCode: number) => t('sideChatBlockExitCode', { code: exitCode }),
|
||||||
|
noExitCode: t('sideChatBlockNoExitCode'),
|
||||||
running: t('sideChatBlockRunning'),
|
running: t('sideChatBlockRunning'),
|
||||||
failed: t('sideChatBlockFailed'),
|
failed: t('sideChatBlockFailed'),
|
||||||
done: t('sideChatBlockDone'),
|
done: t('sideChatBlockDone'),
|
||||||
noOutput: t('sideChatBlockNoOutput'),
|
noOutput: t('sideChatBlockNoOutput'),
|
||||||
},
|
},
|
||||||
diff: { ...shared, files: (count: number) => t('sideChatBlockFiles', { count }) },
|
diff: {
|
||||||
read: { ...shared, window: (shown: number, total: number) => t('sideChatBlockWindow', { shown, total }) },
|
...shared,
|
||||||
|
codeLabel: t('codeLabel'),
|
||||||
|
wrapLabel: t('wrapLabel'),
|
||||||
|
unwrapLabel: t('unwrapLabel'),
|
||||||
|
files: (count: number) => t('sideChatBlockFiles', { count }),
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
...shared,
|
||||||
|
codeLabel: t('codeLabel'),
|
||||||
|
wrapLabel: t('wrapLabel'),
|
||||||
|
unwrapLabel: t('unwrapLabel'),
|
||||||
|
window: (shown: number, total: number) => t('sideChatBlockWindow', { shown, total }),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@@ -593,7 +606,7 @@ export function SideChatView(props: {
|
|||||||
|
|
||||||
const menuItems = useMemo<MenuEntry[]>(() => {
|
const menuItems = useMemo<MenuEntry[]>(() => {
|
||||||
const items: MenuEntry[] = [
|
const items: MenuEntry[] = [
|
||||||
{ id: '$new', label: t('sideChatNew'), icon: <IconPlusOutline16 /> },
|
{ id: '$new', label: t('sideChatNew'), icon: <IconPlusOutlineMedium /> },
|
||||||
]
|
]
|
||||||
if (threads.length > 0) {
|
if (threads.length > 0) {
|
||||||
items.push({ type: 'separator', id: '$sep' })
|
items.push({ type: 'separator', id: '$sep' })
|
||||||
@@ -674,7 +687,7 @@ export function SideChatView(props: {
|
|||||||
return (
|
return (
|
||||||
<div className={css.sidechat}>
|
<div className={css.sidechat}>
|
||||||
<div className={css.sidechatHero}>
|
<div className={css.sidechatHero}>
|
||||||
<IconNewChatOutline16 />
|
<IconNewChatOutlineMedium />
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
css.sidechatHeroTitle,
|
css.sidechatHeroTitle,
|
||||||
@@ -739,7 +752,6 @@ export function SideChatView(props: {
|
|||||||
<ConnectionIndicator
|
<ConnectionIndicator
|
||||||
state={connectionState}
|
state={connectionState}
|
||||||
disconnectedLabel={t('sideChatConnDisconnected')}
|
disconnectedLabel={t('sideChatConnDisconnected')}
|
||||||
reconnectLabel={t('sideChatConnReconnect')}
|
|
||||||
connectingLabel={t('sideChatConnConnecting')}
|
connectingLabel={t('sideChatConnConnecting')}
|
||||||
recoveredLabel={t('sideChatConnRecovered')}
|
recoveredLabel={t('sideChatConnRecovered')}
|
||||||
reconnectActionLabel={t('sideChatConnReconnectAction')}
|
reconnectActionLabel={t('sideChatConnReconnectAction')}
|
||||||
@@ -791,7 +803,7 @@ export function SideChatView(props: {
|
|||||||
disabled={busy !== null}
|
disabled={busy !== null}
|
||||||
title={t('sideChatCancelTitle')}
|
title={t('sideChatCancelTitle')}
|
||||||
>
|
>
|
||||||
<IconStopFill16 />
|
<IconStopFillMedium />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
@@ -802,7 +814,7 @@ export function SideChatView(props: {
|
|||||||
disabled={composer.trim() === '' || busy !== null}
|
disabled={composer.trim() === '' || busy !== null}
|
||||||
title={t('sideChatSend')}
|
title={t('sideChatSend')}
|
||||||
>
|
>
|
||||||
<IconSendOutline16 />
|
<IconSendOutlineMedium />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState, type DragEvent as ReactDragEvent, type ReactNode } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState, type DragEvent as ReactDragEvent, type ReactNode } from 'react'
|
||||||
import { useSyncExternalStore } from 'react'
|
import { useSyncExternalStore } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { IconCloseFill14, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCloseFillRegular, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { Context } from '../context-types.ts'
|
import type { Context } from '../context-types.ts'
|
||||||
import { referenceInChat as referenceInChatShared } from './reference-in-chat.ts'
|
import { referenceInChat as referenceInChatShared } from './reference-in-chat.ts'
|
||||||
import {
|
import {
|
||||||
@@ -784,7 +784,7 @@ export function Sidebar(props: { ctx: Context; store: SidebarStore }) {
|
|||||||
aria-label={t('collapseBottomPanel')}
|
aria-label={t('collapseBottomPanel')}
|
||||||
onClick={() => { store.reduce(toggleBottomPanel) }}
|
onClick={() => { store.reduce(toggleBottomPanel) }}
|
||||||
>
|
>
|
||||||
<IconCloseFill14 />
|
<IconCloseFillRegular />
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div className={css.panelBody}>
|
<div className={css.panelBody}>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent }
|
|||||||
import { useSyncExternalStore } from 'react'
|
import { useSyncExternalStore } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import {
|
import {
|
||||||
IconRefreshOutline14, StateDot,
|
IconRefreshOutlineRegular, StateDot,
|
||||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type {
|
import type {
|
||||||
Context,
|
Context,
|
||||||
@@ -250,7 +250,7 @@ function CatalogRows({
|
|||||||
className={css.subagentErrorRetry}
|
className={css.subagentErrorRetry}
|
||||||
onClick={() => { refresh(parentSessionId) }}
|
onClick={() => { refresh(parentSessionId) }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline14 />
|
<IconRefreshOutlineRegular />
|
||||||
{t('retry')}
|
{t('retry')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -789,7 +789,7 @@ export function SubagentView(props: {
|
|||||||
disabled={rootId === undefined}
|
disabled={rootId === undefined}
|
||||||
onClick={() => { if (rootId !== undefined) refresh(rootId) }}
|
onClick={() => { if (rootId !== undefined) refresh(rootId) }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline14 />
|
<IconRefreshOutlineRegular />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import {
|
import {
|
||||||
IconCloseFill14, IconPlusOutline16, Menu,
|
IconCloseFillRegular, IconPlusOutlineMedium, Menu,
|
||||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { SidebarTab } from './state.ts'
|
import type { SidebarTab } from './state.ts'
|
||||||
import { isAgentTabId } from './state.ts'
|
import { isAgentTabId } from './state.ts'
|
||||||
@@ -241,7 +241,7 @@ export function TabBar(props: {
|
|||||||
onClose(tab.id)
|
onClose(tab.id)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconCloseFill14 />
|
<IconCloseFillRegular />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -275,7 +275,7 @@ export function TabBar(props: {
|
|||||||
title={t('newTab')}
|
title={t('newTab')}
|
||||||
onClick={() => { setMenuOpen(v => !v); setTabMenu(null) }}
|
onClick={() => { setMenuOpen(v => !v); setTabMenu(null) }}
|
||||||
>
|
>
|
||||||
<IconPlusOutline16 />
|
<IconPlusOutlineMedium />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import clsx from 'clsx'
|
|||||||
import { EditorState } from '@codemirror/state'
|
import { EditorState } from '@codemirror/state'
|
||||||
import { EditorView as CodeMirrorView, keymap, lineNumbers } from '@codemirror/view'
|
import { EditorView as CodeMirrorView, keymap, lineNumbers } from '@codemirror/view'
|
||||||
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
|
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
|
||||||
import { IconCheckOutline16, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCheckOutlineMedium, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { markdownTextProps } from './markdown-labels.tsx'
|
import { markdownTextProps } from './markdown-labels.tsx'
|
||||||
import { api, htmlUrl } from './api.ts'
|
import { api, htmlUrl } from './api.ts'
|
||||||
import { markdownPreviewSource } from './markdown-frontmatter.ts'
|
import { markdownPreviewSource } from './markdown-frontmatter.ts'
|
||||||
@@ -462,7 +462,7 @@ export function TextEditor(props: FileViewerProps) {
|
|||||||
title={`${t('save')} (Ctrl/Cmd+S)`}
|
title={`${t('save')} (Ctrl/Cmd+S)`}
|
||||||
onClick={save}
|
onClick={save}
|
||||||
>
|
>
|
||||||
<IconCheckOutline16 />
|
<IconCheckOutlineMedium />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{saveLabel !== '' && <span className={clsx(css.editorStatus, saveState === 'failed' && css.editorStatusError)}>{saveLabel}</span>}
|
{saveLabel !== '' && <span className={clsx(css.editorStatus, saveState === 'failed' && css.editorStatusError)}>{saveLabel}</span>}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
import { useEffect, useRef, useState, type InputHTMLAttributes } from 'react'
|
import { useEffect, useRef, useState, type InputHTMLAttributes } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { IconFolderOpen16, IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconFolderOpenMedium, IconRefreshOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { api } from './api.ts'
|
import { api } from './api.ts'
|
||||||
import type { BetterSidebarService } from './service.ts'
|
import type { BetterSidebarService } from './service.ts'
|
||||||
import type { SidebarStore } from './state.ts'
|
import type { SidebarStore } from './state.ts'
|
||||||
@@ -195,7 +195,7 @@ export function TreePanel(props: {
|
|||||||
title={t('refresh')}
|
title={t('refresh')}
|
||||||
onClick={() => { setRefreshTick(tick => tick + 1) }}
|
onClick={() => { setRefreshTick(tick => tick + 1) }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline16 size={14} />
|
<IconRefreshOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -215,7 +215,7 @@ export function TreePanel(props: {
|
|||||||
disabled={busy}
|
disabled={busy}
|
||||||
onClick={() => { folderInputRef.current?.click() }}
|
onClick={() => { folderInputRef.current?.click() }}
|
||||||
>
|
>
|
||||||
<IconFolderOpen16 size={14} />
|
<IconFolderOpenMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
<input
|
<input
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* `browser:<n>` the same way (no quota). The editor IS the files window
|
* `browser:<n>` the same way (no quota). The editor IS the files window
|
||||||
* (the old standalone explorer merged into it).
|
* (the old standalone explorer merged into it).
|
||||||
*/
|
*/
|
||||||
import { IconCodeOutline16, IconPanelLeftOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCodeOutlineMedium, IconPanelLeftOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { Context } from '../../context-types.ts'
|
import type { Context } from '../../context-types.ts'
|
||||||
import {
|
import {
|
||||||
browserTabIcon, changesTabIcon, filesTabIcon, sidechatTabIcon, tasksTabIcon, terminalTabIcon,
|
browserTabIcon, changesTabIcon, filesTabIcon, sidechatTabIcon, tasksTabIcon, terminalTabIcon,
|
||||||
@@ -109,13 +109,13 @@ export function builtinTabs(ctx: Context, options: BuiltinTabOptions = {}): read
|
|||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: true,
|
value: true,
|
||||||
icon: (size: number) => <IconPanelLeftOutline16 size={size} />,
|
icon: (size: number) => <IconPanelLeftOutlineMedium size={size} />,
|
||||||
title: () => t('editorExplorerMerged'),
|
title: () => t('editorExplorerMerged'),
|
||||||
desc: () => t('editorExplorerMergedDesc'),
|
desc: () => t('editorExplorerMergedDesc'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: false,
|
value: false,
|
||||||
icon: (size: number) => <IconCodeOutline16 size={size} />,
|
icon: (size: number) => <IconCodeOutlineMedium size={size} />,
|
||||||
title: () => t('editorExplorerSplit'),
|
title: () => t('editorExplorerSplit'),
|
||||||
desc: () => t('editorExplorerSplitDesc'),
|
desc: () => t('editorExplorerSplitDesc'),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
* and `icon` — so the Side card settings page can render the enable/disable
|
* and `icon` — so the Side card settings page can render the enable/disable
|
||||||
* inventory without hardcoding (eating our own dogfood).
|
* inventory without hardcoding (eating our own dogfood).
|
||||||
*/
|
*/
|
||||||
import { IconCodeOutline16, IconDownloadOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCodeOutlineMedium, IconDownloadOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { lazyChunkComponent } from '../lazy-chunk.tsx'
|
import { lazyChunkComponent } from '../lazy-chunk.tsx'
|
||||||
import { PdfView } from '../PdfView.tsx'
|
import { PdfView } from '../PdfView.tsx'
|
||||||
import { BinaryDownload } from '../binary-download.tsx'
|
import { BinaryDownload } from '../binary-download.tsx'
|
||||||
@@ -103,7 +103,7 @@ export function builtinViewers(): readonly FileViewerDescriptor[] {
|
|||||||
{
|
{
|
||||||
id: 'code',
|
id: 'code',
|
||||||
title: () => t('viewerCode'),
|
title: () => t('viewerCode'),
|
||||||
icon: (size: number) => <IconCodeOutline16 size={size} />,
|
icon: (size: number) => <IconCodeOutlineMedium size={size} />,
|
||||||
exts: [],
|
exts: [],
|
||||||
priority: -100,
|
priority: -100,
|
||||||
fetchStrategy: 'fsRead',
|
fetchStrategy: 'fsRead',
|
||||||
@@ -112,7 +112,7 @@ export function builtinViewers(): readonly FileViewerDescriptor[] {
|
|||||||
{
|
{
|
||||||
id: 'binary-download',
|
id: 'binary-download',
|
||||||
title: () => t('viewerBinary'),
|
title: () => t('viewerBinary'),
|
||||||
icon: (size: number) => <IconDownloadOutline16 size={size} />,
|
icon: (size: number) => <IconDownloadOutlineMedium size={size} />,
|
||||||
exts: ['doc', 'xls', 'ppt'],
|
exts: ['doc', 'xls', 'ppt'],
|
||||||
priority: -50,
|
priority: -50,
|
||||||
fetchStrategy: 'binary-download',
|
fetchStrategy: 'binary-download',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* diff tab via the shell.
|
* diff tab via the shell.
|
||||||
*/
|
*/
|
||||||
import { useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointerEvent } from 'react'
|
import { useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointerEvent } from 'react'
|
||||||
import { IconCloseOutline16, IconRefreshOutline16, IconRightUpOutline16, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCloseOutlineMedium, IconRefreshOutlineMedium, IconRightUpOutlineMedium, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { SessionScope } from '../api.ts'
|
import type { SessionScope } from '../api.ts'
|
||||||
import { api, htmlUrl } from '../api.ts'
|
import { api, htmlUrl } from '../api.ts'
|
||||||
import { t } from '../locales.ts'
|
import { t } from '../locales.ts'
|
||||||
@@ -491,7 +491,7 @@ export function DiffPane({ target, scope, height, onHeightCommit, onClose, onExp
|
|||||||
disabled={loading}
|
disabled={loading}
|
||||||
onClick={() => { setTick(value => value + 1) }}
|
onClick={() => { setTick(value => value + 1) }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline16 size={14} />
|
<IconRefreshOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -500,7 +500,7 @@ export function DiffPane({ target, scope, height, onHeightCommit, onClose, onExp
|
|||||||
title={t('changesOpenDiffTab')}
|
title={t('changesOpenDiffTab')}
|
||||||
onClick={onExpand}
|
onClick={onExpand}
|
||||||
>
|
>
|
||||||
<IconRightUpOutline16 size={14} />
|
<IconRightUpOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -543,7 +543,7 @@ export function DiffPane({ target, scope, height, onHeightCommit, onClose, onExp
|
|||||||
title={t('changesClosePreview')}
|
title={t('changesClosePreview')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
<IconCloseOutline16 size={14} />
|
<IconCloseOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{target.kind === 'op' && htmlOp && rendering && htmlRenderSrc !== ''
|
{target.kind === 'op' && htmlOp && rendering && htmlRenderSrc !== ''
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
import { useCallback, useEffect, useRef, useState, type MouseEvent, type ReactNode } from 'react'
|
import { useCallback, useEffect, useRef, useState, type MouseEvent, type ReactNode } from 'react'
|
||||||
import {
|
import {
|
||||||
Button, IconCodeOutline16, IconCopyOutline16, IconPlusOutline16,
|
Button, IconCodeOutlineMedium, IconCopyOutlineMedium, IconPlusOutlineMedium,
|
||||||
IconRefreshOutline16, IconTrashOutline16, Input, Menu, Modal, writeClipboard,
|
IconRefreshOutlineMedium, IconTrashOutlineMedium, Input, Menu, Modal, writeClipboard,
|
||||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { GitLogEntry, GitStatusEntry, GitStatusResult, GitWorktree, SessionScope } from '../api.ts'
|
import type { GitLogEntry, GitStatusEntry, GitStatusResult, GitWorktree, SessionScope } from '../api.ts'
|
||||||
import { api } from '../api.ts'
|
import { api } from '../api.ts'
|
||||||
@@ -450,7 +450,7 @@ export function GitLens(props: GitLensProps) {
|
|||||||
disabled={busy}
|
disabled={busy}
|
||||||
onClick={() => { void stageEntry(entry, staged) }}
|
onClick={() => { void stageEntry(entry, staged) }}
|
||||||
>
|
>
|
||||||
{staged ? <IconTrashOutline16 /> : <IconPlusOutline16 />}
|
{staged ? <IconTrashOutlineMedium /> : <IconPlusOutlineMedium />}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -504,7 +504,7 @@ export function GitLens(props: GitLensProps) {
|
|||||||
title={t('refresh')}
|
title={t('refresh')}
|
||||||
onClick={() => { void refresh() }}
|
onClick={() => { void refresh() }}
|
||||||
>
|
>
|
||||||
<IconRefreshOutline16 size={14} />
|
<IconRefreshOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -624,17 +624,17 @@ export function GitLens(props: GitLensProps) {
|
|||||||
// that confuses the user; with the fence disarmed (the
|
// that confuses the user; with the fence disarmed (the
|
||||||
// `workspaceFence` pref) the open is allowed through.
|
// `workspaceFence` pref) the open is allowed through.
|
||||||
...(fileMenu !== null && (store.getPrefs().workspaceFence === false || isWithinWorkspace(scope.cwd ?? '', resolveSidebarPath(repoRoot ?? selectedWorktree ?? scope.cwd, fileMenu.entry.path)))
|
...(fileMenu !== null && (store.getPrefs().workspaceFence === false || isWithinWorkspace(scope.cwd ?? '', resolveSidebarPath(repoRoot ?? selectedWorktree ?? scope.cwd, fileMenu.entry.path)))
|
||||||
? [{ id: 'open', label: t('openEditor'), icon: <IconCodeOutline16 size={14} /> }]
|
? [{ id: 'open', label: t('openEditor'), icon: <IconCodeOutlineMedium size={14} /> }]
|
||||||
: []),
|
: []),
|
||||||
fileMenu?.staged === true
|
fileMenu?.staged === true
|
||||||
? { id: 'stage', label: t('unstage'), icon: <IconTrashOutline16 size={14} /> }
|
? { id: 'stage', label: t('unstage'), icon: <IconTrashOutlineMedium size={14} /> }
|
||||||
: { id: 'stage', label: t('stage'), icon: <IconPlusOutline16 size={14} /> },
|
: { id: 'stage', label: t('stage'), icon: <IconPlusOutlineMedium size={14} /> },
|
||||||
...(fileMenu !== null && !isUntracked(fileMenu.entry)
|
...(fileMenu !== null && !isUntracked(fileMenu.entry)
|
||||||
? [{ id: 'discard', label: t('discard'), icon: <IconTrashOutline16 size={14} />, danger: true }]
|
? [{ id: 'discard', label: t('discard'), icon: <IconTrashOutlineMedium size={14} />, danger: true }]
|
||||||
: []),
|
: []),
|
||||||
{ type: 'separator', id: 'sep1' },
|
{ type: 'separator', id: 'sep1' },
|
||||||
{ id: 'relative', label: t('copyRelative'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'relative', label: t('copyRelative'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
{ id: 'absolute', label: t('copyAbsolute'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'absolute', label: t('copyAbsolute'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
]}
|
]}
|
||||||
onSelect={(id) => {
|
onSelect={(id) => {
|
||||||
const target = fileMenu
|
const target = fileMenu
|
||||||
@@ -683,9 +683,9 @@ export function GitLens(props: GitLensProps) {
|
|||||||
onClose={() => { setHistoryMenu(null) }}
|
onClose={() => { setHistoryMenu(null) }}
|
||||||
items={[
|
items={[
|
||||||
{ id: 'view', label: t('viewCommitDiff') },
|
{ id: 'view', label: t('viewCommitDiff') },
|
||||||
{ id: 'copyShort', label: t('copyShortHash'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'copyShort', label: t('copyShortHash'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
{ id: 'copyFull', label: t('copyFullHash'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'copyFull', label: t('copyFullHash'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
{ id: 'copySubject', label: t('copySubject'), icon: <IconCopyOutline16 size={14} /> },
|
{ id: 'copySubject', label: t('copySubject'), icon: <IconCopyOutlineMedium size={14} /> },
|
||||||
{ type: 'separator', id: 'sep2' },
|
{ type: 'separator', id: 'sep2' },
|
||||||
{ id: 'revert', label: t('revertCommit'), danger: true },
|
{ id: 'revert', label: t('revertCommit'), danger: true },
|
||||||
{ id: 'cherryPick', label: t('cherryPickCommit'), danger: true },
|
{ id: 'cherryPick', label: t('cherryPickCommit'), danger: true },
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* deliverables entry; when nothing was produced the selector returns null
|
* deliverables entry; when nothing was produced the selector returns null
|
||||||
* and the original row renders unchanged.
|
* and the original row renders unchanged.
|
||||||
*/
|
*/
|
||||||
import { IconCodeOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCodeOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import type { Context } from '../context-types.ts'
|
import type { Context } from '../context-types.ts'
|
||||||
import { revealPaths, type SidebarStore } from './state.ts'
|
import { revealPaths, type SidebarStore } from './state.ts'
|
||||||
import { t } from './locales.ts'
|
import { t } from './locales.ts'
|
||||||
@@ -59,6 +59,7 @@ export function SidebarProducedFiles(props: {
|
|||||||
onShowInFolder: (files: readonly string[]) => void
|
onShowInFolder: (files: readonly string[]) => void
|
||||||
}) {
|
}) {
|
||||||
const { matched, openInSidebar, onShowInFolder } = props
|
const { matched, openInSidebar, onShowInFolder } = props
|
||||||
|
if (!matched || matched.length === 0) return null
|
||||||
const shown = matched.slice(0, 6)
|
const shown = matched.slice(0, 6)
|
||||||
const hidden = matched.length - shown.length
|
const hidden = matched.length - shown.length
|
||||||
return (
|
return (
|
||||||
@@ -75,7 +76,7 @@ export function SidebarProducedFiles(props: {
|
|||||||
title={path}
|
title={path}
|
||||||
onClick={() => { openInSidebar(path) }}
|
onClick={() => { openInSidebar(path) }}
|
||||||
>
|
>
|
||||||
<IconCodeOutline16 size={12} />
|
<IconCodeOutlineMedium size={12} />
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -369,6 +369,14 @@ export const ar: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'قيد التشغيل',
|
sideChatBlockRunning: 'قيد التشغيل',
|
||||||
sideChatBlockFailed: 'فشل',
|
sideChatBlockFailed: 'فشل',
|
||||||
sideChatBlockDone: 'اكتمل',
|
sideChatBlockDone: 'اكتمل',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(لا يوجد إخراج)',
|
sideChatBlockNoOutput: '(لا يوجد إخراج)',
|
||||||
sideChatBlockFiles: '{count} ملفات',
|
sideChatBlockFiles: '{count} ملفات',
|
||||||
sideChatBlockWindow: '{shown} من {total} سطرًا',
|
sideChatBlockWindow: '{shown} من {total} سطرًا',
|
||||||
|
|||||||
@@ -354,6 +354,13 @@ export const de: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Läuft',
|
sideChatBlockRunning: 'Läuft',
|
||||||
sideChatBlockFailed: 'Fehlgeschlagen',
|
sideChatBlockFailed: 'Fehlgeschlagen',
|
||||||
sideChatBlockDone: 'Fertig',
|
sideChatBlockDone: 'Fertig',
|
||||||
|
sideChatBlockNoExitCode: '(kein Exit-Code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
sideChatBlockNoOutput: '(keine Ausgabe)',
|
sideChatBlockNoOutput: '(keine Ausgabe)',
|
||||||
sideChatBlockFiles: '{count} Dateien',
|
sideChatBlockFiles: '{count} Dateien',
|
||||||
sideChatBlockWindow: '{shown} von {total} Zeilen',
|
sideChatBlockWindow: '{shown} von {total} Zeilen',
|
||||||
|
|||||||
@@ -361,6 +361,14 @@ export const fr: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'En cours',
|
sideChatBlockRunning: 'En cours',
|
||||||
sideChatBlockFailed: 'Échec',
|
sideChatBlockFailed: 'Échec',
|
||||||
sideChatBlockDone: 'Terminé',
|
sideChatBlockDone: 'Terminé',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(aucune sortie)',
|
sideChatBlockNoOutput: '(aucune sortie)',
|
||||||
sideChatBlockFiles: '{count} fichiers',
|
sideChatBlockFiles: '{count} fichiers',
|
||||||
sideChatBlockWindow: '{shown} sur {total} lignes',
|
sideChatBlockWindow: '{shown} sur {total} lignes',
|
||||||
|
|||||||
@@ -368,6 +368,14 @@ export const hi: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'चल रहा है',
|
sideChatBlockRunning: 'चल रहा है',
|
||||||
sideChatBlockFailed: 'विफल',
|
sideChatBlockFailed: 'विफल',
|
||||||
sideChatBlockDone: 'पूर्ण',
|
sideChatBlockDone: 'पूर्ण',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(कोई आउटपुट नहीं)',
|
sideChatBlockNoOutput: '(कोई आउटपुट नहीं)',
|
||||||
sideChatBlockFiles: '{count} फ़ाइलें',
|
sideChatBlockFiles: '{count} फ़ाइलें',
|
||||||
sideChatBlockWindow: 'कुल {total} में से {shown} पंक्तियाँ',
|
sideChatBlockWindow: 'कुल {total} में से {shown} पंक्तियाँ',
|
||||||
|
|||||||
@@ -366,6 +366,14 @@ export const id: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Berjalan',
|
sideChatBlockRunning: 'Berjalan',
|
||||||
sideChatBlockFailed: 'Gagal',
|
sideChatBlockFailed: 'Gagal',
|
||||||
sideChatBlockDone: 'Selesai',
|
sideChatBlockDone: 'Selesai',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(tanpa output)',
|
sideChatBlockNoOutput: '(tanpa output)',
|
||||||
sideChatBlockFiles: '{count} file',
|
sideChatBlockFiles: '{count} file',
|
||||||
sideChatBlockWindow: '{shown} dari {total} baris',
|
sideChatBlockWindow: '{shown} dari {total} baris',
|
||||||
|
|||||||
@@ -359,6 +359,14 @@ export const it: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'In esecuzione',
|
sideChatBlockRunning: 'In esecuzione',
|
||||||
sideChatBlockFailed: 'Non riuscito',
|
sideChatBlockFailed: 'Non riuscito',
|
||||||
sideChatBlockDone: 'Completato',
|
sideChatBlockDone: 'Completato',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(nessun output)',
|
sideChatBlockNoOutput: '(nessun output)',
|
||||||
sideChatBlockFiles: '{count} file',
|
sideChatBlockFiles: '{count} file',
|
||||||
sideChatBlockWindow: '{shown} di {total} righe',
|
sideChatBlockWindow: '{shown} di {total} righe',
|
||||||
|
|||||||
@@ -368,6 +368,14 @@ export const ja: Record<string, string> = {
|
|||||||
sideChatBlockRunning: '実行中',
|
sideChatBlockRunning: '実行中',
|
||||||
sideChatBlockFailed: '失敗',
|
sideChatBlockFailed: '失敗',
|
||||||
sideChatBlockDone: '完了',
|
sideChatBlockDone: '完了',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(出力なし)',
|
sideChatBlockNoOutput: '(出力なし)',
|
||||||
sideChatBlockFiles: '{count} 個のファイル',
|
sideChatBlockFiles: '{count} 個のファイル',
|
||||||
sideChatBlockWindow: '全 {total} 行中 {shown} 行を表示',
|
sideChatBlockWindow: '全 {total} 行中 {shown} 行を表示',
|
||||||
|
|||||||
@@ -360,6 +360,14 @@ export const ko: Record<string, string> = {
|
|||||||
sideChatBlockRunning: '실행 중',
|
sideChatBlockRunning: '실행 중',
|
||||||
sideChatBlockFailed: '실패',
|
sideChatBlockFailed: '실패',
|
||||||
sideChatBlockDone: '완료',
|
sideChatBlockDone: '완료',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(출력 없음)',
|
sideChatBlockNoOutput: '(출력 없음)',
|
||||||
sideChatBlockFiles: '파일 {count}개',
|
sideChatBlockFiles: '파일 {count}개',
|
||||||
sideChatBlockWindow: '전체 {total}줄 중 {shown}줄 표시',
|
sideChatBlockWindow: '전체 {total}줄 중 {shown}줄 표시',
|
||||||
|
|||||||
@@ -366,6 +366,13 @@ export const nl: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Wordt uitgevoerd',
|
sideChatBlockRunning: 'Wordt uitgevoerd',
|
||||||
sideChatBlockFailed: 'Mislukt',
|
sideChatBlockFailed: 'Mislukt',
|
||||||
sideChatBlockDone: 'Voltooid',
|
sideChatBlockDone: 'Voltooid',
|
||||||
|
sideChatBlockNoExitCode: '(geen exitcode)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
sideChatBlockNoOutput: '(geen uitvoer)',
|
sideChatBlockNoOutput: '(geen uitvoer)',
|
||||||
sideChatBlockFiles: '{count} bestanden',
|
sideChatBlockFiles: '{count} bestanden',
|
||||||
sideChatBlockWindow: '{shown} van {total} regels',
|
sideChatBlockWindow: '{shown} van {total} regels',
|
||||||
|
|||||||
@@ -370,6 +370,14 @@ export const pl: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Uruchomione',
|
sideChatBlockRunning: 'Uruchomione',
|
||||||
sideChatBlockFailed: 'Niepowodzenie',
|
sideChatBlockFailed: 'Niepowodzenie',
|
||||||
sideChatBlockDone: 'Zakończono',
|
sideChatBlockDone: 'Zakończono',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(brak wyniku)',
|
sideChatBlockNoOutput: '(brak wyniku)',
|
||||||
sideChatBlockFiles: 'Pliki: {count}',
|
sideChatBlockFiles: 'Pliki: {count}',
|
||||||
sideChatBlockWindow: '{shown} z {total} wierszy',
|
sideChatBlockWindow: '{shown} z {total} wierszy',
|
||||||
|
|||||||
@@ -351,6 +351,14 @@ export const pt: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Em execução',
|
sideChatBlockRunning: 'Em execução',
|
||||||
sideChatBlockFailed: 'Falhou',
|
sideChatBlockFailed: 'Falhou',
|
||||||
sideChatBlockDone: 'Concluído',
|
sideChatBlockDone: 'Concluído',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(sem saída)',
|
sideChatBlockNoOutput: '(sem saída)',
|
||||||
sideChatBlockFiles: '{count} arquivos',
|
sideChatBlockFiles: '{count} arquivos',
|
||||||
sideChatBlockWindow: '{shown} de {total} linhas',
|
sideChatBlockWindow: '{shown} de {total} linhas',
|
||||||
|
|||||||
@@ -366,6 +366,14 @@ export const ru: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Выполняется',
|
sideChatBlockRunning: 'Выполняется',
|
||||||
sideChatBlockFailed: 'Ошибка',
|
sideChatBlockFailed: 'Ошибка',
|
||||||
sideChatBlockDone: 'Готово',
|
sideChatBlockDone: 'Готово',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(нет вывода)',
|
sideChatBlockNoOutput: '(нет вывода)',
|
||||||
sideChatBlockFiles: 'Файлов: {count}',
|
sideChatBlockFiles: 'Файлов: {count}',
|
||||||
sideChatBlockWindow: '{shown} из {total} строк',
|
sideChatBlockWindow: '{shown} из {total} строк',
|
||||||
|
|||||||
@@ -351,6 +351,14 @@ export const sv: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Körs',
|
sideChatBlockRunning: 'Körs',
|
||||||
sideChatBlockFailed: 'Misslyckades',
|
sideChatBlockFailed: 'Misslyckades',
|
||||||
sideChatBlockDone: 'Klar',
|
sideChatBlockDone: 'Klar',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(ingen utdata)',
|
sideChatBlockNoOutput: '(ingen utdata)',
|
||||||
sideChatBlockFiles: '{count} filer',
|
sideChatBlockFiles: '{count} filer',
|
||||||
sideChatBlockWindow: '{shown} av {total} rader',
|
sideChatBlockWindow: '{shown} av {total} rader',
|
||||||
|
|||||||
@@ -368,6 +368,14 @@ export const th: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'กำลังทำงาน',
|
sideChatBlockRunning: 'กำลังทำงาน',
|
||||||
sideChatBlockFailed: 'ล้มเหลว',
|
sideChatBlockFailed: 'ล้มเหลว',
|
||||||
sideChatBlockDone: 'เสร็จสิ้น',
|
sideChatBlockDone: 'เสร็จสิ้น',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(ไม่มีเอาต์พุต)',
|
sideChatBlockNoOutput: '(ไม่มีเอาต์พุต)',
|
||||||
sideChatBlockFiles: '{count} ไฟล์',
|
sideChatBlockFiles: '{count} ไฟล์',
|
||||||
sideChatBlockWindow: '{shown} จาก {total} บรรทัด',
|
sideChatBlockWindow: '{shown} จาก {total} บรรทัด',
|
||||||
|
|||||||
@@ -368,6 +368,14 @@ export const tr: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Çalışıyor',
|
sideChatBlockRunning: 'Çalışıyor',
|
||||||
sideChatBlockFailed: 'Başarısız',
|
sideChatBlockFailed: 'Başarısız',
|
||||||
sideChatBlockDone: 'Tamamlandı',
|
sideChatBlockDone: 'Tamamlandı',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(çıktı yok)',
|
sideChatBlockNoOutput: '(çıktı yok)',
|
||||||
sideChatBlockFiles: '{count} dosya',
|
sideChatBlockFiles: '{count} dosya',
|
||||||
sideChatBlockWindow: '{total} satırdan {shown} satır',
|
sideChatBlockWindow: '{total} satırdan {shown} satır',
|
||||||
|
|||||||
@@ -368,6 +368,14 @@ export const vi: Record<string, string> = {
|
|||||||
sideChatBlockRunning: 'Đang chạy',
|
sideChatBlockRunning: 'Đang chạy',
|
||||||
sideChatBlockFailed: 'Thất bại',
|
sideChatBlockFailed: 'Thất bại',
|
||||||
sideChatBlockDone: 'Hoàn tất',
|
sideChatBlockDone: 'Hoàn tất',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: 'Code',
|
||||||
|
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(không có đầu ra)',
|
sideChatBlockNoOutput: '(không có đầu ra)',
|
||||||
sideChatBlockFiles: '{count} tệp',
|
sideChatBlockFiles: '{count} tệp',
|
||||||
sideChatBlockWindow: '{shown} trong {total} dòng',
|
sideChatBlockWindow: '{shown} trong {total} dòng',
|
||||||
|
|||||||
@@ -383,6 +383,14 @@ export const zhHK: Record<string, string> = {
|
|||||||
sideChatBlockRunning: '執行中',
|
sideChatBlockRunning: '執行中',
|
||||||
sideChatBlockFailed: '失敗',
|
sideChatBlockFailed: '失敗',
|
||||||
sideChatBlockDone: '完成',
|
sideChatBlockDone: '完成',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: '代码',
|
||||||
|
|
||||||
|
wrapLabel: '换行',
|
||||||
|
|
||||||
|
unwrapLabel: '不换行',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(無輸出)',
|
sideChatBlockNoOutput: '(無輸出)',
|
||||||
sideChatBlockFiles: '{count} 個檔案',
|
sideChatBlockFiles: '{count} 個檔案',
|
||||||
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
||||||
|
|||||||
@@ -383,6 +383,14 @@ export const zhMO: Record<string, string> = {
|
|||||||
sideChatBlockRunning: '執行中',
|
sideChatBlockRunning: '執行中',
|
||||||
sideChatBlockFailed: '失敗',
|
sideChatBlockFailed: '失敗',
|
||||||
sideChatBlockDone: '完成',
|
sideChatBlockDone: '完成',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: '代码',
|
||||||
|
|
||||||
|
wrapLabel: '换行',
|
||||||
|
|
||||||
|
unwrapLabel: '不换行',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(無輸出)',
|
sideChatBlockNoOutput: '(無輸出)',
|
||||||
sideChatBlockFiles: '{count} 個檔案',
|
sideChatBlockFiles: '{count} 個檔案',
|
||||||
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
||||||
|
|||||||
@@ -383,6 +383,14 @@ export const zhTW: Record<string, string> = {
|
|||||||
sideChatBlockRunning: '執行中',
|
sideChatBlockRunning: '執行中',
|
||||||
sideChatBlockFailed: '失敗',
|
sideChatBlockFailed: '失敗',
|
||||||
sideChatBlockDone: '完成',
|
sideChatBlockDone: '完成',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
|
||||||
|
codeLabel: '代码',
|
||||||
|
|
||||||
|
wrapLabel: '换行',
|
||||||
|
|
||||||
|
unwrapLabel: '不换行',
|
||||||
|
|
||||||
sideChatBlockNoOutput: '(無輸出)',
|
sideChatBlockNoOutput: '(無輸出)',
|
||||||
sideChatBlockFiles: '{count} 個檔案',
|
sideChatBlockFiles: '{count} 個檔案',
|
||||||
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
sideChatBlockWindow: '共 {total} 行 · 顯示 {shown} 行',
|
||||||
|
|||||||
@@ -380,6 +380,13 @@ export const zh = {
|
|||||||
sideChatBlockRunning: '运行中',
|
sideChatBlockRunning: '运行中',
|
||||||
sideChatBlockFailed: '失败',
|
sideChatBlockFailed: '失败',
|
||||||
sideChatBlockDone: '完成',
|
sideChatBlockDone: '完成',
|
||||||
|
sideChatBlockNoExitCode: '无退出码',
|
||||||
|
|
||||||
|
codeLabel: '代码',
|
||||||
|
|
||||||
|
wrapLabel: '换行',
|
||||||
|
|
||||||
|
unwrapLabel: '不换行',
|
||||||
sideChatBlockNoOutput: '(无输出)',
|
sideChatBlockNoOutput: '(无输出)',
|
||||||
sideChatBlockFiles: '{count} 个文件',
|
sideChatBlockFiles: '{count} 个文件',
|
||||||
sideChatBlockWindow: '共 {total} 行 · 显示 {shown} 行',
|
sideChatBlockWindow: '共 {total} 行 · 显示 {shown} 行',
|
||||||
@@ -822,6 +829,10 @@ export const en: Record<keyof typeof zh, string> = {
|
|||||||
sideChatBlockRunning: 'Running',
|
sideChatBlockRunning: 'Running',
|
||||||
sideChatBlockFailed: 'Failed',
|
sideChatBlockFailed: 'Failed',
|
||||||
sideChatBlockDone: 'Done',
|
sideChatBlockDone: 'Done',
|
||||||
|
sideChatBlockNoExitCode: '(no exit code)',
|
||||||
|
codeLabel: 'Code',
|
||||||
|
wrapLabel: 'Wrap',
|
||||||
|
unwrapLabel: 'Unwrap',
|
||||||
sideChatBlockNoOutput: '(no output)',
|
sideChatBlockNoOutput: '(no output)',
|
||||||
sideChatBlockFiles: '{count} files',
|
sideChatBlockFiles: '{count} files',
|
||||||
sideChatBlockWindow: '{shown} of {total} lines',
|
sideChatBlockWindow: '{shown} of {total} lines',
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
import { useLayoutEffect, useRef, useState } from 'react'
|
import { useLayoutEffect, useRef, useState } from 'react'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import { IconListPenOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconListPenOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { t } from './locales.ts'
|
import { t } from './locales.ts'
|
||||||
import css from './sidebar.module.css'
|
import css from './sidebar.module.css'
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ export function MdToc(): ReactNode {
|
|||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
onClick={() => { setOpen(!open) }}
|
onClick={() => { setOpen(!open) }}
|
||||||
>
|
>
|
||||||
<IconListPenOutline16 />
|
<IconListPenOutlineMedium />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { useCallback, useEffect, useLayoutEffect, useRef, useState, type MouseEv
|
|||||||
import { createPortal } from 'react-dom'
|
import { createPortal } from 'react-dom'
|
||||||
import { createRoot, type Root } from 'react-dom/client'
|
import { createRoot, type Root } from 'react-dom/client'
|
||||||
import mermaid from 'mermaid'
|
import mermaid from 'mermaid'
|
||||||
import { IconCopyOutline16, MarkdownText, writeClipboard } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCopyOutlineMedium, MarkdownText, writeClipboard } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import { isDarkScheme, subscribeColorScheme } from './theme.ts'
|
import { isDarkScheme, subscribeColorScheme } from './theme.ts'
|
||||||
import { markdownTextProps } from './markdown-labels.tsx'
|
import { markdownTextProps } from './markdown-labels.tsx'
|
||||||
import { t } from './locales.ts'
|
import { t } from './locales.ts'
|
||||||
@@ -288,7 +288,7 @@ function MermaidDiagram({ code }: { code: string }): React.ReactNode {
|
|||||||
aria-label={t('copy')}
|
aria-label={t('copy')}
|
||||||
title={t('copy')}
|
title={t('copy')}
|
||||||
>
|
>
|
||||||
<IconCopyOutline16 />
|
<IconCopyOutlineMedium />
|
||||||
<span>{copied ? t('copied') : t('copy')}</span>
|
<span>{copied ? t('copied') : t('copy')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* this component owns only its own section.
|
* this component owns only its own section.
|
||||||
*/
|
*/
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { IconCloseOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
import { IconCloseOutlineMedium } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||||
import {
|
import {
|
||||||
isValidCustomEditor,
|
isValidCustomEditor,
|
||||||
newCustomEditorId,
|
newCustomEditorId,
|
||||||
@@ -121,7 +121,7 @@ export function OpenWithSettings(props: {
|
|||||||
title={t('openWithSettingsRemove')}
|
title={t('openWithSettingsRemove')}
|
||||||
onClick={() => { removeCustom(editor.id) }}
|
onClick={() => { removeCustom(editor.id) }}
|
||||||
>
|
>
|
||||||
<IconCloseOutline16 size={14} />
|
<IconCloseOutlineMedium size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import {
|
|||||||
liveEventsOf,
|
liveEventsOf,
|
||||||
resolvePresetId,
|
resolvePresetId,
|
||||||
SIDE_BOUNDARY_PROMPT,
|
SIDE_BOUNDARY_PROMPT,
|
||||||
SIDE_INJECTION_PLUGIN,
|
|
||||||
SIDE_NEW_THREAD_TITLE,
|
SIDE_NEW_THREAD_TITLE,
|
||||||
sideLabel,
|
sideLabel,
|
||||||
type SeedEvent,
|
type SeedEvent,
|
||||||
@@ -159,7 +158,7 @@ function admitFollowup(agent: Agent, blocks: ContentBlock[]): void {
|
|||||||
function admitFirstContact(agent: Agent, injectionText: string, question: string): void {
|
function admitFirstContact(agent: Agent, injectionText: string, question: string): void {
|
||||||
agent.inject(createUserMessage({
|
agent.inject(createUserMessage({
|
||||||
content: textPrompt(injectionText),
|
content: textPrompt(injectionText),
|
||||||
source: { kind: 'plugin', plugin: SIDE_INJECTION_PLUGIN },
|
source: { kind: 'user' },
|
||||||
}))
|
}))
|
||||||
admitFollowup(agent, textPrompt(question))
|
admitFollowup(agent, textPrompt(question))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { describe, expect, it, vi } from 'vitest'
|
|||||||
import { SUBAGENT_DESCRIPTOR_VERSION } from '@deepseek-ai/dsh-subagent'
|
import { SUBAGENT_DESCRIPTOR_VERSION } from '@deepseek-ai/dsh-subagent'
|
||||||
import { buildSidechatApi } from '../src/sidechat-routes.ts'
|
import { buildSidechatApi } from '../src/sidechat-routes.ts'
|
||||||
import { SidebarError } from '../src/wire.ts'
|
import { SidebarError } from '../src/wire.ts'
|
||||||
import { SIDE_BOUNDARY_PROMPT, SIDE_INJECTION_PLUGIN, SIDE_NEW_THREAD_TITLE, sideLabel } from '../src/sidechat-core.ts'
|
import { SIDE_BOUNDARY_PROMPT, SIDE_NEW_THREAD_TITLE, sideLabel } from '../src/sidechat-core.ts'
|
||||||
import type { Context } from '../src/context-types.ts'
|
import type { Context } from '../src/context-types.ts'
|
||||||
|
|
||||||
/** A fake live agent (inject/followup/cancel spied). */
|
/** A fake live agent (inject/followup/cancel spied). */
|
||||||
@@ -165,7 +165,7 @@ describe('sidechat.start', () => {
|
|||||||
// context, no wake), the question is the follow-up that wakes the driver.
|
// context, no wake), the question is the follow-up that wakes the driver.
|
||||||
expect(child.inject).toHaveBeenCalledTimes(1)
|
expect(child.inject).toHaveBeenCalledTimes(1)
|
||||||
const injection = child.inject.mock.calls[0]![0] as { content: Array<{ type: string; text: string }>; source: { kind: string; plugin: string } }
|
const injection = child.inject.mock.calls[0]![0] as { content: Array<{ type: string; text: string }>; source: { kind: string; plugin: string } }
|
||||||
expect(injection.source).toEqual({ kind: 'plugin', plugin: SIDE_INJECTION_PLUGIN })
|
expect(injection.source).toEqual({ kind: 'user' })
|
||||||
expect(injection.content[0]!.text.startsWith(SIDE_BOUNDARY_PROMPT)).toBe(true)
|
expect(injection.content[0]!.text.startsWith(SIDE_BOUNDARY_PROMPT)).toBe(true)
|
||||||
expect(injection.content[0]!.text).not.toContain('explain the event flow')
|
expect(injection.content[0]!.text).not.toContain('explain the event flow')
|
||||||
expect(child.followup).toHaveBeenCalledTimes(1)
|
expect(child.followup).toHaveBeenCalledTimes(1)
|
||||||
@@ -259,7 +259,7 @@ describe('sidechat.start', () => {
|
|||||||
await api['sidechat.prompt']({ childId, text: 'explain the event flow' })
|
await api['sidechat.prompt']({ childId, text: 'explain the event flow' })
|
||||||
expect(child.inject).toHaveBeenCalledTimes(1)
|
expect(child.inject).toHaveBeenCalledTimes(1)
|
||||||
const injection = child.inject.mock.calls[0]![0] as { content: Array<{ text: string }>; source: { kind: string } }
|
const injection = child.inject.mock.calls[0]![0] as { content: Array<{ text: string }>; source: { kind: string } }
|
||||||
expect(injection.source.kind).toBe('plugin')
|
expect(injection.source.kind).toBe('user')
|
||||||
expect(injection.content[0]!.text.startsWith(SIDE_BOUNDARY_PROMPT)).toBe(true)
|
expect(injection.content[0]!.text.startsWith(SIDE_BOUNDARY_PROMPT)).toBe(true)
|
||||||
expect(injection.content[0]!.text).toContain('`bash` (executing)')
|
expect(injection.content[0]!.text).toContain('`bash` (executing)')
|
||||||
expect(child.followup).toHaveBeenCalledTimes(1)
|
expect(child.followup).toHaveBeenCalledTimes(1)
|
||||||
|
|||||||
@@ -185,7 +185,8 @@ describe('sidechat seed fork markers vs the reconstructed inbox', () => {
|
|||||||
turn: 2, step: 1,
|
turn: 2, step: 1,
|
||||||
message: {
|
message: {
|
||||||
id: 'm-r',
|
id: 'm-r',
|
||||||
role: 'user',
|
role: 'tool',
|
||||||
|
toolCallId: 'c1',
|
||||||
content: [{ type: 'tool-result', toolCallId: 'c1', content: [{ type: 'text', text: 'ok' }] }],
|
content: [{ type: 'tool-result', toolCallId: 'c1', content: [{ type: 'text', text: 'ok' }] }],
|
||||||
source: { kind: 'tool', callId: 'c1' },
|
source: { kind: 'tool', callId: 'c1' },
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user