@steerable/agent-shell-web 0.6.27 → 0.6.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/AgentSidebar.tsx +27 -27
- package/src/components/BrandLockup.tsx +20 -4
- package/src/components/ChatHeader.tsx +5 -15
- package/src/components/LocalLlmSettingsModal.tsx +5 -5
- package/src/components/TerminalPanel.tsx +1 -1
- package/src/components/chat/ApprovalModal.tsx +5 -5
- package/src/components/chat/AskUserQuestionMenu.tsx +13 -13
- package/src/components/chat/AssistantMessage.tsx +122 -36
- package/src/components/chat/ChatInput.tsx +34 -26
- package/src/components/chat/ExecPolicyPicker.tsx +4 -4
- package/src/components/chat/ExecutedActionsCard.tsx +398 -29
- package/src/components/chat/FilePathCode.tsx +2 -1
- package/src/components/chat/LocalChatPanel.tsx +42 -11
- package/src/components/chat/Markdown.tsx +15 -14
- package/src/components/chat/MessageList.tsx +23 -5
- package/src/components/chat/ModelPicker.tsx +6 -6
- package/src/components/chat/OrchestrationChildrenCard.tsx +69 -5
- package/src/components/chat/SessionTodoList.tsx +234 -0
- package/src/components/chat/SessionTreeModal.tsx +3 -3
- package/src/components/chat/SuggestedReplies.tsx +14 -5
- package/src/components/chat/TaskPanelModal.tsx +3 -3
- package/src/components/chat/TaskProcessPanel.tsx +67 -21
- package/src/components/chat/TurnFilesCard.tsx +2 -2
- package/src/components/chat/TurnProcessGroup.tsx +252 -99
- package/src/components/chat/UserMessage.tsx +7 -7
- package/src/components/chat/executed-actions-model.ts +469 -0
- package/src/components/chat/next-steps-tags.ts +28 -0
- package/src/components/chat/orchestration-children-model.ts +120 -0
- package/src/components/chat/process-status.ts +125 -53
- package/src/components/chat/todo-list-model.ts +167 -0
- package/src/components/chat/turn-timeline.ts +123 -11
- package/src/components/settings/AgentsSettingsPanel.tsx +2 -2
- package/src/components/settings/AppearanceSettingsPanel.tsx +3 -3
- package/src/components/settings/DiagnoseSettingsPanel.tsx +2 -2
- package/src/components/settings/InsightsSettingsPanel.tsx +4 -4
- package/src/components/settings/LlmSettingsPanel.tsx +10 -10
- package/src/components/settings/McpSettingsPanel.tsx +3 -3
- package/src/components/settings/ModelIdCombobox.tsx +2 -2
- package/src/components/settings/SecuritySettingsPanel.tsx +1 -1
- package/src/components/settings/SettingsSaveButton.tsx +1 -1
- package/src/components/settings/SkillsSettingsPanel.tsx +2 -2
- package/src/components/settings/TelemetrySettingsPanel.tsx +2 -2
- package/src/components/settings/UsagePanel.tsx +14 -10
- package/src/components/settings/WebSearchSettingsPanel.tsx +2 -2
- package/src/layouts/AgentLayout.tsx +3 -3
- package/src/lib/chat-transport.ts +68 -12
- package/src/lib/local-api.ts +11 -0
- package/src/lib/show-thinking-content.ts +4 -4
- package/src/pages/AgentPage.tsx +82 -11
- package/src/pages/ChatPanelPreviewPage.tsx +26 -4
- package/src/pages/SettingsPage.tsx +39 -39
- package/src/styles/index.css +12 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steerable/agent-shell-web",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Steerable framework — product-neutral renderer SPA source for @steerable/agent-shell (React + Vite). Consumed by product web entry points via the `@/` alias (anchored at this package's src/) and the createProductViteConfig factory. Published as a source package (src/), plus the compiled vite.base config factory (vite.base.js + .d.ts) for Node-side config loading.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"react-router-dom": "^6.30.0",
|
|
47
47
|
"rehype-raw": "^7.0.0",
|
|
48
48
|
"remark-gfm": "^4.0.1",
|
|
49
|
-
"@steerable/agent-
|
|
50
|
-
"@steerable/agent-
|
|
49
|
+
"@steerable/agent-ui": "0.6.29",
|
|
50
|
+
"@steerable/agent-protocol": "0.6.29"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@tailwindcss/vite": "^4.3.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"typescript": "^5.8.3",
|
|
61
61
|
"vite": "^5.4.21",
|
|
62
62
|
"vitest": "^3.2.4",
|
|
63
|
-
"@steerable/pack-sdk": "0.6.
|
|
63
|
+
"@steerable/pack-sdk": "0.6.29"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"gen": "echo agent-shell-web",
|
|
@@ -477,7 +477,7 @@ export function AgentSidebar({
|
|
|
477
477
|
navigate(`/agent/${chat.id}`);
|
|
478
478
|
}}
|
|
479
479
|
className={[
|
|
480
|
-
'flex h-
|
|
480
|
+
'flex h-7 w-full min-w-0 items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors duration-200',
|
|
481
481
|
isCurrent
|
|
482
482
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
483
483
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -620,8 +620,8 @@ export function AgentSidebar({
|
|
|
620
620
|
return (
|
|
621
621
|
<div className="flex h-full w-full flex-col border-r border-agent-border/60 bg-agent-muted/70 backdrop-blur-md">
|
|
622
622
|
{/* ───── Brand + actions ───── */}
|
|
623
|
-
<div className="flex h-
|
|
624
|
-
<BrandLockup />
|
|
623
|
+
<div className="flex h-9 flex-shrink-0 items-center justify-between px-2.5">
|
|
624
|
+
<BrandLockup onClick={() => handleOpenNewChat()} />
|
|
625
625
|
<div className="flex items-center gap-1">
|
|
626
626
|
<button
|
|
627
627
|
type="button"
|
|
@@ -638,12 +638,12 @@ export function AgentSidebar({
|
|
|
638
638
|
{/* ───── 会话 ───── */}
|
|
639
639
|
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
|
|
640
640
|
{/* 新对话 + 智能体 / Skill / MCP 设置入口 — 横版行按钮,各自打开独立设置页 */}
|
|
641
|
-
<div className="flex-shrink-0 space-y-0.5 px-
|
|
641
|
+
<div className="flex-shrink-0 space-y-0.5 px-2.5 pb-0.5">
|
|
642
642
|
<button
|
|
643
643
|
type="button"
|
|
644
644
|
onClick={() => handleOpenNewChat()}
|
|
645
645
|
className={[
|
|
646
|
-
'flex h-
|
|
646
|
+
'flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
647
647
|
onNewChatHome
|
|
648
648
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
649
649
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -651,14 +651,14 @@ export function AgentSidebar({
|
|
|
651
651
|
title="新建对话"
|
|
652
652
|
data-testid="sidebar-new-chat"
|
|
653
653
|
>
|
|
654
|
-
<LuPlus className="h-
|
|
654
|
+
<LuPlus className="h-3.5 w-3.5" />
|
|
655
655
|
<span>新对话</span>
|
|
656
656
|
</button>
|
|
657
657
|
<button
|
|
658
658
|
type="button"
|
|
659
659
|
onClick={() => navigate('/settings?section=agents')}
|
|
660
660
|
className={[
|
|
661
|
-
'flex h-
|
|
661
|
+
'flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
662
662
|
onSettingsPage && settingsSection === 'agents'
|
|
663
663
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
664
664
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -666,14 +666,14 @@ export function AgentSidebar({
|
|
|
666
666
|
title="智能体管理"
|
|
667
667
|
data-testid="sidebar-agent-settings"
|
|
668
668
|
>
|
|
669
|
-
<LuBot className="h-
|
|
669
|
+
<LuBot className="h-3.5 w-3.5" />
|
|
670
670
|
<span>智能体管理</span>
|
|
671
671
|
</button>
|
|
672
672
|
<button
|
|
673
673
|
type="button"
|
|
674
674
|
onClick={() => navigate('/settings?section=skills')}
|
|
675
675
|
className={[
|
|
676
|
-
'flex h-
|
|
676
|
+
'flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
677
677
|
onSettingsPage && settingsSection === 'skills'
|
|
678
678
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
679
679
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -681,14 +681,14 @@ export function AgentSidebar({
|
|
|
681
681
|
title="Skill 设置"
|
|
682
682
|
data-testid="sidebar-skill-settings"
|
|
683
683
|
>
|
|
684
|
-
<LuBlocks className="h-
|
|
684
|
+
<LuBlocks className="h-3.5 w-3.5" />
|
|
685
685
|
<span>Skill 设置</span>
|
|
686
686
|
</button>
|
|
687
687
|
<button
|
|
688
688
|
type="button"
|
|
689
689
|
onClick={() => navigate('/settings?section=mcp')}
|
|
690
690
|
className={[
|
|
691
|
-
'flex h-
|
|
691
|
+
'flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
692
692
|
onSettingsPage && settingsSection === 'mcp'
|
|
693
693
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
694
694
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -696,15 +696,15 @@ export function AgentSidebar({
|
|
|
696
696
|
title="MCP 设置"
|
|
697
697
|
data-testid="sidebar-mcp-settings"
|
|
698
698
|
>
|
|
699
|
-
<LuPlug className="h-
|
|
699
|
+
<LuPlug className="h-3.5 w-3.5" />
|
|
700
700
|
<span>MCP 设置</span>
|
|
701
701
|
</button>
|
|
702
702
|
</div>
|
|
703
|
-
<div className="flex flex-shrink-0 items-center justify-between py-1
|
|
703
|
+
<div className="flex flex-shrink-0 items-center justify-between py-1 pl-2.5 pr-2.5">
|
|
704
704
|
<button
|
|
705
705
|
type="button"
|
|
706
706
|
onClick={() => setChatsExpanded((v) => !v)}
|
|
707
|
-
className="flex items-center text-xs font-semibold tracking-wider text-agent-muted-foreground transition-colors hover:text-agent-foreground"
|
|
707
|
+
className="flex h-6 items-center rounded-full px-2.5 text-xs font-semibold tracking-wider text-agent-muted-foreground transition-colors hover:bg-agent-foreground/5 hover:text-agent-foreground"
|
|
708
708
|
>
|
|
709
709
|
<span className="mr-1">
|
|
710
710
|
{chatsExpanded ? (
|
|
@@ -739,7 +739,7 @@ export function AgentSidebar({
|
|
|
739
739
|
{chatsExpanded && (
|
|
740
740
|
<div
|
|
741
741
|
ref={chatScrollRef}
|
|
742
|
-
className="flex-1 overflow-y-auto px-2 pb-1"
|
|
742
|
+
className="flex-1 overflow-y-auto px-2.5 pb-1"
|
|
743
743
|
>
|
|
744
744
|
{isChatLoading && chats.length === 0 && projects.length === 0 ? (
|
|
745
745
|
<div className="flex items-center justify-center py-4 text-xs text-agent-muted-foreground">
|
|
@@ -747,7 +747,7 @@ export function AgentSidebar({
|
|
|
747
747
|
加载中...
|
|
748
748
|
</div>
|
|
749
749
|
) : chatGroups.length === 0 && projectGroups.length === 0 ? (
|
|
750
|
-
<div className="flex flex-col items-center gap-1.5 py-
|
|
750
|
+
<div className="flex flex-col items-center gap-1.5 py-4 text-xs text-agent-muted-foreground">
|
|
751
751
|
<LuMessageSquare className="h-4 w-4 text-agent-muted-foreground/60" />
|
|
752
752
|
暂无会话
|
|
753
753
|
</div>
|
|
@@ -759,7 +759,7 @@ export function AgentSidebar({
|
|
|
759
759
|
<div className="group/proj relative">
|
|
760
760
|
{renamingProjectId === project.id ? (
|
|
761
761
|
<form
|
|
762
|
-
className="flex items-center px-
|
|
762
|
+
className="flex items-center px-2.5 pb-1 pt-1.5"
|
|
763
763
|
onSubmit={(event) => {
|
|
764
764
|
event.preventDefault();
|
|
765
765
|
void handleRenameProject(project.id);
|
|
@@ -781,7 +781,7 @@ export function AgentSidebar({
|
|
|
781
781
|
<button
|
|
782
782
|
type="button"
|
|
783
783
|
onClick={() => toggleProjectCollapsed(project.id)}
|
|
784
|
-
className="flex w-full min-w-0 items-center px-
|
|
784
|
+
className="flex w-full min-w-0 items-center px-2.5 pb-0.5 pt-1.5 text-[10px] font-medium uppercase tracking-wider text-agent-muted-foreground/80 transition-colors hover:text-agent-foreground"
|
|
785
785
|
title={`${project.name}\n${project.folderPath}`}
|
|
786
786
|
>
|
|
787
787
|
<span className="mr-1">
|
|
@@ -856,7 +856,7 @@ export function AgentSidebar({
|
|
|
856
856
|
{!collapsedProjectIds.has(project.id) && (
|
|
857
857
|
<div className="space-y-0.5">
|
|
858
858
|
{items.length === 0 ? (
|
|
859
|
-
<div className="px-
|
|
859
|
+
<div className="px-2.5 py-0.5 text-[11px] text-agent-muted-foreground/60">
|
|
860
860
|
暂无会话 — hover 项目名点 + 新建
|
|
861
861
|
</div>
|
|
862
862
|
) : (
|
|
@@ -869,7 +869,7 @@ export function AgentSidebar({
|
|
|
869
869
|
{/* 无项目对话排在项目分组之后:保持原有日期分组 */}
|
|
870
870
|
{chatGroups.map((group) => (
|
|
871
871
|
<div key={group.label} className="mb-1">
|
|
872
|
-
<div className="px-
|
|
872
|
+
<div className="px-2.5 pb-0.5 pt-1.5 text-[10px] font-medium uppercase tracking-wider text-agent-muted-foreground/80">
|
|
873
873
|
{group.label}
|
|
874
874
|
</div>
|
|
875
875
|
<div className="space-y-0.5">
|
|
@@ -899,7 +899,7 @@ export function AgentSidebar({
|
|
|
899
899
|
|
|
900
900
|
{(error || projectError) && (
|
|
901
901
|
<div
|
|
902
|
-
className="flex-shrink-0 border-t border-agent-destructive/40 bg-agent-destructive/10 px-
|
|
902
|
+
className="flex-shrink-0 border-t border-agent-destructive/40 bg-agent-destructive/10 px-2.5 py-1.5 text-[11px] text-agent-destructive"
|
|
903
903
|
role="alert"
|
|
904
904
|
>
|
|
905
905
|
{error ?? projectError}
|
|
@@ -907,13 +907,13 @@ export function AgentSidebar({
|
|
|
907
907
|
)}
|
|
908
908
|
|
|
909
909
|
{/* ───── Footer: 右侧面板切换(终端 | 包槽位)+ 设置 ───── */}
|
|
910
|
-
<div className="flex-shrink-0 border-t border-agent-border/40 px-
|
|
910
|
+
<div className="flex-shrink-0 border-t border-agent-border/40 px-2.5 py-1.5">
|
|
911
911
|
{chatSlots.length === 0 ? (
|
|
912
912
|
<button
|
|
913
913
|
type="button"
|
|
914
914
|
onClick={() => onToggleRightPanel('terminal')}
|
|
915
915
|
className={[
|
|
916
|
-
'flex h-
|
|
916
|
+
'flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
917
917
|
rightPanel === 'terminal'
|
|
918
918
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
919
919
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-foreground',
|
|
@@ -921,7 +921,7 @@ export function AgentSidebar({
|
|
|
921
921
|
title={`${rightPanel === 'terminal' ? '关闭' : '打开'}终端面板 (${isMac ? '⌘T' : 'Ctrl+T'})`}
|
|
922
922
|
data-testid="sidebar-terminal"
|
|
923
923
|
>
|
|
924
|
-
<LuTerminal className="h-
|
|
924
|
+
<LuTerminal className="h-3.5 w-3.5" />
|
|
925
925
|
<span>终端</span>
|
|
926
926
|
<span className="ml-auto text-[10px] text-agent-muted-foreground/70">
|
|
927
927
|
{isMac ? '⌘T' : 'Ctrl+T'}
|
|
@@ -931,7 +931,7 @@ export function AgentSidebar({
|
|
|
931
931
|
<div
|
|
932
932
|
role="group"
|
|
933
933
|
aria-label="右侧面板切换"
|
|
934
|
-
className="flex h-
|
|
934
|
+
className="flex h-7 w-full items-center gap-0.5 rounded-full bg-agent-foreground/5 p-0.5"
|
|
935
935
|
>
|
|
936
936
|
<button
|
|
937
937
|
type="button"
|
|
@@ -972,7 +972,7 @@ export function AgentSidebar({
|
|
|
972
972
|
type="button"
|
|
973
973
|
onClick={() => navigate('/settings')}
|
|
974
974
|
className={[
|
|
975
|
-
'mt-0.5 flex h-
|
|
975
|
+
'mt-0.5 flex h-7 w-full items-center gap-1.5 rounded-full px-2.5 text-xs transition-colors',
|
|
976
976
|
onGeneralSettings
|
|
977
977
|
? 'bg-agent-foreground/10 font-medium text-agent-foreground'
|
|
978
978
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground',
|
|
@@ -980,7 +980,7 @@ export function AgentSidebar({
|
|
|
980
980
|
title="设置"
|
|
981
981
|
data-testid="sidebar-llm-settings"
|
|
982
982
|
>
|
|
983
|
-
<LuSettings className="h-
|
|
983
|
+
<LuSettings className="h-3.5 w-3.5" />
|
|
984
984
|
<span>设置</span>
|
|
985
985
|
</button>
|
|
986
986
|
</div>
|
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
import { BRAND_NAME, BRAND_TITLE, getBrandLogoUrl } from '@/brand';
|
|
2
2
|
|
|
3
|
+
export interface BrandLockupProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
/**
|
|
4
9
|
* 侧栏品牌锁头。配了 brand.title 就 logo + 标题;没配标题则只显示 logo,
|
|
5
10
|
* 并按原图宽高比缩放(一体字标不要压成方图)。
|
|
11
|
+
* 自带 px-2.5 内边距,与侧边栏下方各功能行、会话行的图标在一条垂直参考线上(left: 20px)精准对齐。
|
|
6
12
|
*/
|
|
7
|
-
export function BrandLockup() {
|
|
13
|
+
export function BrandLockup({ className, onClick }: BrandLockupProps = {}) {
|
|
8
14
|
const title = BRAND_TITLE.trim();
|
|
9
15
|
return (
|
|
10
|
-
<div
|
|
16
|
+
<div
|
|
17
|
+
onClick={onClick}
|
|
18
|
+
className={[
|
|
19
|
+
'flex min-w-0 items-center gap-2 px-2.5',
|
|
20
|
+
onClick ? 'cursor-pointer select-none transition-opacity hover:opacity-85' : '',
|
|
21
|
+
className,
|
|
22
|
+
]
|
|
23
|
+
.filter(Boolean)
|
|
24
|
+
.join(' ')}
|
|
25
|
+
>
|
|
11
26
|
<img
|
|
12
27
|
src={getBrandLogoUrl()}
|
|
13
28
|
alt={title || BRAND_NAME}
|
|
14
|
-
className=
|
|
29
|
+
className={`${title ? 'h-5' : 'h-6'} w-auto max-w-[10rem] flex-shrink-0 select-none object-contain object-left`}
|
|
15
30
|
draggable={false}
|
|
16
31
|
/>
|
|
17
32
|
{title ? (
|
|
18
|
-
<span className="truncate text-
|
|
33
|
+
<span className="truncate text-xs font-semibold tracking-tight text-agent-foreground leading-none">
|
|
19
34
|
{title}
|
|
20
35
|
</span>
|
|
21
36
|
) : null}
|
|
22
37
|
</div>
|
|
23
38
|
);
|
|
24
39
|
}
|
|
40
|
+
|
|
@@ -127,7 +127,7 @@ export function ChatHeader({
|
|
|
127
127
|
data-branch-menu
|
|
128
128
|
>
|
|
129
129
|
{!branches || branchCount === 0 ? (
|
|
130
|
-
<div className="px-
|
|
130
|
+
<div className="px-2.5 py-1.5 text-xs text-agent-muted-foreground">
|
|
131
131
|
暂无分支 — 重新生成回复后,旧版本会保留在这里。
|
|
132
132
|
</div>
|
|
133
133
|
) : (
|
|
@@ -159,7 +159,7 @@ export function ChatHeader({
|
|
|
159
159
|
setBranchMenuOpen(false);
|
|
160
160
|
setTreeModalOpen(true);
|
|
161
161
|
}}
|
|
162
|
-
className="flex w-full items-center gap-2 rounded px-
|
|
162
|
+
className="flex w-full items-center gap-2 rounded px-2.5 py-1 text-left text-xs text-agent-muted-foreground transition-colors hover:bg-agent-foreground/5 hover:text-agent-foreground"
|
|
163
163
|
data-action="branch-tree"
|
|
164
164
|
>
|
|
165
165
|
<LuListTree className="h-3 w-3 shrink-0" />
|
|
@@ -174,19 +174,14 @@ export function ChatHeader({
|
|
|
174
174
|
: null;
|
|
175
175
|
|
|
176
176
|
return (
|
|
177
|
-
<header className="flex w-full min-w-0 items-center gap-
|
|
177
|
+
<header className="flex w-full min-w-0 items-center gap-2 bg-agent-canvas px-2.5 py-1.5">
|
|
178
178
|
<div className="flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-0.5">
|
|
179
179
|
<span
|
|
180
|
-
className="break-words text-
|
|
180
|
+
className="break-words text-xs font-medium text-agent-foreground"
|
|
181
181
|
title={chat?.title}
|
|
182
182
|
>
|
|
183
183
|
{chat?.title ?? '未选择对话'}
|
|
184
184
|
</span>
|
|
185
|
-
{chat && (
|
|
186
|
-
<span className="hidden shrink-0 font-mono text-[10px] text-agent-muted-foreground/70 md:inline">
|
|
187
|
-
{shortenId(chat.id)}
|
|
188
|
-
</span>
|
|
189
|
-
)}
|
|
190
185
|
</div>
|
|
191
186
|
{chat && onBranchSwitched && (
|
|
192
187
|
<div className="shrink-0">
|
|
@@ -367,11 +362,6 @@ function taskButtonTitle(
|
|
|
367
362
|
: `${base} · 点击处理 worktree`;
|
|
368
363
|
}
|
|
369
364
|
|
|
370
|
-
function shortenId(id: string): string {
|
|
371
|
-
if (id.length <= 12) return id;
|
|
372
|
-
return `${id.slice(0, 6)}…${id.slice(-4)}`;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
365
|
/** Pin the branch menu to the trigger, clamped inside the chat panel so
|
|
376
366
|
* `overflow-hidden` ancestors cannot clip the left side of a `w-72` sheet. */
|
|
377
367
|
function placeBranchMenu(button: HTMLElement): { top: number; left: number; width: number } {
|
|
@@ -403,7 +393,7 @@ function BranchRow({
|
|
|
403
393
|
onClick={onSelect}
|
|
404
394
|
aria-current={active ? 'true' : undefined}
|
|
405
395
|
aria-disabled={disabled || active || undefined}
|
|
406
|
-
className={`flex w-full items-center gap-2 rounded px-
|
|
396
|
+
className={`flex w-full items-center gap-2 rounded px-2.5 py-1 text-left text-xs transition-colors ${
|
|
407
397
|
active
|
|
408
398
|
? 'cursor-default bg-agent-foreground/5 font-medium text-agent-foreground'
|
|
409
399
|
: 'text-agent-muted-foreground hover:bg-agent-foreground/5 hover:text-agent-foreground'
|
|
@@ -42,8 +42,8 @@ export function LocalLlmSettingsModal({ open, onClose, onSaved }: LocalLlmSettin
|
|
|
42
42
|
<div
|
|
43
43
|
className="flex h-[560px] max-h-[90vh] w-[540px] max-w-[92vw] flex-col overflow-hidden rounded-agent-lg border border-agent-border bg-agent-canvas shadow-2xl animate-fade-in"
|
|
44
44
|
>
|
|
45
|
-
<div className="flex h-
|
|
46
|
-
<h2 className="text-
|
|
45
|
+
<div className="flex h-9 flex-shrink-0 items-center justify-between border-b border-agent-border px-3">
|
|
46
|
+
<h2 className="text-xs font-semibold text-agent-foreground">本地模型设置</h2>
|
|
47
47
|
<button
|
|
48
48
|
type="button"
|
|
49
49
|
onClick={onClose}
|
|
@@ -53,14 +53,14 @@ export function LocalLlmSettingsModal({ open, onClose, onSaved }: LocalLlmSettin
|
|
|
53
53
|
<LuX className="h-4 w-4" />
|
|
54
54
|
</button>
|
|
55
55
|
</div>
|
|
56
|
-
<div className="flex-1 overflow-y-auto p-
|
|
56
|
+
<div className="flex-1 overflow-y-auto p-3">
|
|
57
57
|
<LlmSettingsPanel onSaved={onSaved} />
|
|
58
58
|
</div>
|
|
59
|
-
<div className="flex h-
|
|
59
|
+
<div className="flex h-9 flex-shrink-0 items-center justify-end border-t border-agent-border px-3 bg-agent-muted/10">
|
|
60
60
|
<button
|
|
61
61
|
type="button"
|
|
62
62
|
onClick={onClose}
|
|
63
|
-
className="h-
|
|
63
|
+
className="h-7 rounded-full px-3 text-xs font-medium text-agent-muted-foreground transition-colors hover:bg-agent-muted hover:text-agent-foreground"
|
|
64
64
|
>
|
|
65
65
|
关闭
|
|
66
66
|
</button>
|
|
@@ -40,7 +40,7 @@ export function TerminalPanel({
|
|
|
40
40
|
}
|
|
41
41
|
if (!hasElectron) {
|
|
42
42
|
return (
|
|
43
|
-
<div className="flex h-full w-full items-center justify-center bg-black p-
|
|
43
|
+
<div className="flex h-full w-full items-center justify-center bg-black p-4 text-center font-mono text-xs text-white">
|
|
44
44
|
<div>
|
|
45
45
|
<p className="mb-2">⚠️ 此面板需要桌面客户端或 BS server 连接。</p>
|
|
46
46
|
<p className="text-white/60">
|
|
@@ -106,17 +106,17 @@ export function ApprovalPromptMenu({
|
|
|
106
106
|
|
|
107
107
|
return (
|
|
108
108
|
<div
|
|
109
|
-
className="overflow-hidden rounded-agent-lg border border-agent-border bg-agent-canvas text-
|
|
109
|
+
className="overflow-hidden rounded-agent-lg border border-agent-border bg-agent-canvas text-xs text-agent-foreground shadow-xl"
|
|
110
110
|
data-testid="approval-composer"
|
|
111
111
|
>
|
|
112
|
-
<div className="flex items-center gap-2 border-b border-agent-border px-
|
|
112
|
+
<div className="flex items-center gap-2 border-b border-agent-border px-3 py-2">
|
|
113
113
|
{destructive ? (
|
|
114
114
|
<LuTriangleAlert className="h-4 w-4 shrink-0 text-agent-destructive" />
|
|
115
115
|
) : (
|
|
116
116
|
<LuShieldAlert className="h-4 w-4 shrink-0 text-amber-500" />
|
|
117
117
|
)}
|
|
118
118
|
<div className="min-w-0 flex-1">
|
|
119
|
-
<div className="text-
|
|
119
|
+
<div className="text-xs font-medium text-agent-foreground">
|
|
120
120
|
{isEgress ? (
|
|
121
121
|
<>
|
|
122
122
|
Agent 请求访问外网
|
|
@@ -143,7 +143,7 @@ export function ApprovalPromptMenu({
|
|
|
143
143
|
</div>
|
|
144
144
|
</div>
|
|
145
145
|
|
|
146
|
-
<div className="max-h-48 overflow-auto px-
|
|
146
|
+
<div className="max-h-48 overflow-auto px-3 py-2">
|
|
147
147
|
<pre className="whitespace-pre-wrap break-all rounded-agent-md bg-agent-muted/50 px-3 py-2 font-mono text-xs text-agent-foreground">
|
|
148
148
|
{summarizeArguments(current.arguments)}
|
|
149
149
|
</pre>
|
|
@@ -169,7 +169,7 @@ export function ApprovalPromptMenu({
|
|
|
169
169
|
)}
|
|
170
170
|
</div>
|
|
171
171
|
|
|
172
|
-
<div className="space-y-2 border-t border-agent-border px-
|
|
172
|
+
<div className="space-y-2 border-t border-agent-border px-3 py-2">
|
|
173
173
|
<DecisionRow
|
|
174
174
|
buttons={
|
|
175
175
|
isEgress
|
|
@@ -120,7 +120,7 @@ function Footer({
|
|
|
120
120
|
children?: React.ReactNode;
|
|
121
121
|
}) {
|
|
122
122
|
return (
|
|
123
|
-
<div className="mt-
|
|
123
|
+
<div className="mt-3 flex items-center justify-between gap-2 border-t border-agent-border px-3 py-2">
|
|
124
124
|
<div className="flex min-w-0 items-center gap-2">
|
|
125
125
|
{canGoBack && onBack && (
|
|
126
126
|
<button
|
|
@@ -279,7 +279,7 @@ function SelectQuestionStep({
|
|
|
279
279
|
role={question.multiSelect ? 'checkbox' : 'radio'}
|
|
280
280
|
aria-checked={active}
|
|
281
281
|
className={[
|
|
282
|
-
'flex w-full items-center gap-2 rounded-agent-md border px-3 py-2 text-left text-
|
|
282
|
+
'flex w-full items-center gap-2 rounded-agent-md border px-3 py-2 text-left text-xs transition',
|
|
283
283
|
active
|
|
284
284
|
? 'border-agent-foreground bg-agent-muted text-agent-foreground'
|
|
285
285
|
: 'border-agent-border bg-agent-canvas text-agent-foreground hover:bg-agent-muted',
|
|
@@ -335,7 +335,7 @@ function SelectQuestionStep({
|
|
|
335
335
|
role={question.multiSelect ? 'checkbox' : 'radio'}
|
|
336
336
|
aria-checked={active}
|
|
337
337
|
className={[
|
|
338
|
-
'flex w-full items-center gap-2 rounded-agent-md border border-dashed px-3 py-2 text-left text-
|
|
338
|
+
'flex w-full items-center gap-2 rounded-agent-md border border-dashed px-3 py-2 text-left text-xs transition',
|
|
339
339
|
active
|
|
340
340
|
? 'border-agent-foreground bg-agent-muted text-agent-foreground'
|
|
341
341
|
: 'border-agent-border bg-agent-canvas text-agent-muted-foreground hover:bg-agent-muted hover:text-agent-foreground',
|
|
@@ -359,13 +359,13 @@ function SelectQuestionStep({
|
|
|
359
359
|
|
|
360
360
|
return (
|
|
361
361
|
<div>
|
|
362
|
-
<div className="space-y-2 px-
|
|
362
|
+
<div className="space-y-2 px-3 py-2">
|
|
363
363
|
{question.header && (
|
|
364
364
|
<p className="text-[11px] font-medium uppercase tracking-wide text-agent-muted-foreground">
|
|
365
365
|
{question.header}
|
|
366
366
|
</p>
|
|
367
367
|
)}
|
|
368
|
-
<p className="text-
|
|
368
|
+
<p className="text-xs font-medium text-agent-foreground">{question.text}</p>
|
|
369
369
|
{question.detail && (
|
|
370
370
|
<p className="whitespace-pre-line text-xs text-agent-muted-foreground">
|
|
371
371
|
{question.detail}
|
|
@@ -396,7 +396,7 @@ function SelectQuestionStep({
|
|
|
396
396
|
}
|
|
397
397
|
}}
|
|
398
398
|
placeholder={question.placeholder || '输入你的补充...'}
|
|
399
|
-
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-
|
|
399
|
+
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-xs text-agent-foreground outline-none placeholder:text-agent-muted-foreground focus:border-agent-foreground focus:ring-1 focus:ring-agent-foreground"
|
|
400
400
|
/>
|
|
401
401
|
)}
|
|
402
402
|
|
|
@@ -414,7 +414,7 @@ function SelectQuestionStep({
|
|
|
414
414
|
}
|
|
415
415
|
}}
|
|
416
416
|
placeholder={question.placeholder || '输入你的回答...'}
|
|
417
|
-
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-
|
|
417
|
+
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-xs text-agent-foreground outline-none placeholder:text-agent-muted-foreground focus:border-agent-foreground focus:ring-1 focus:ring-agent-foreground"
|
|
418
418
|
/>
|
|
419
419
|
<button
|
|
420
420
|
type="button"
|
|
@@ -488,13 +488,13 @@ function TextQuestionStep({
|
|
|
488
488
|
|
|
489
489
|
return (
|
|
490
490
|
<div>
|
|
491
|
-
<div className="space-y-2 px-
|
|
491
|
+
<div className="space-y-2 px-3 py-2">
|
|
492
492
|
{question.header && (
|
|
493
493
|
<p className="text-[11px] font-medium uppercase tracking-wide text-agent-muted-foreground">
|
|
494
494
|
{question.header}
|
|
495
495
|
</p>
|
|
496
496
|
)}
|
|
497
|
-
<p className="text-
|
|
497
|
+
<p className="text-xs font-medium text-agent-foreground">{question.text}</p>
|
|
498
498
|
{question.detail && (
|
|
499
499
|
<p className="whitespace-pre-line text-xs text-agent-muted-foreground">
|
|
500
500
|
{question.detail}
|
|
@@ -512,7 +512,7 @@ function TextQuestionStep({
|
|
|
512
512
|
}
|
|
513
513
|
}}
|
|
514
514
|
placeholder={question.placeholder || '输入你的回答...'}
|
|
515
|
-
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-
|
|
515
|
+
className="w-full rounded-agent-md border border-agent-border bg-agent-canvas px-3 py-2 text-xs text-agent-foreground outline-none placeholder:text-agent-muted-foreground focus:border-agent-foreground focus:ring-1 focus:ring-agent-foreground"
|
|
516
516
|
/>
|
|
517
517
|
</div>
|
|
518
518
|
|
|
@@ -577,10 +577,10 @@ export function AskUserQuestionMenu({
|
|
|
577
577
|
if (!current) return null;
|
|
578
578
|
|
|
579
579
|
return (
|
|
580
|
-
<div className="overflow-hidden rounded-agent-lg border border-agent-border bg-agent-canvas text-
|
|
581
|
-
<div className="flex items-start justify-between gap-
|
|
580
|
+
<div className="overflow-hidden rounded-agent-lg border border-agent-border bg-agent-canvas text-xs text-agent-foreground shadow-xl">
|
|
581
|
+
<div className="flex items-start justify-between gap-2 border-b border-agent-border px-3 py-2">
|
|
582
582
|
<div className="min-w-0 flex-1">
|
|
583
|
-
<p className="text-
|
|
583
|
+
<p className="text-xs font-medium text-agent-foreground">
|
|
584
584
|
{intro || '需要你的输入'}
|
|
585
585
|
</p>
|
|
586
586
|
<p className="mt-0.5 text-[11px] text-agent-muted-foreground">
|