Skip to content

Commit d4fc2dc

Browse files
authored
Merge pull request #3460 from bobleer/feat/desktop-cards
feat(desktop-cards): show persistent glanceable cards outside the main window
2 parents b3728e6 + aec1a9a commit d4fc2dc

97 files changed

Lines changed: 8535 additions & 123 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎design-system/apps/design-lab/src/i18n/semanticToolMessages.ts‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const semanticToolEn = {
1919
"flowChat.builtin.tools.PublishMiniApp": "Submit Mini App",
2020
"flowChat.builtin.tools.PublishAppearance": "Submit Skin",
2121
"flowChat.builtin.tools.Playbook": "Read operation guide",
22+
"flowChat.builtin.tools.DesktopCard": "Desktop card",
2223
"flowChat.builtin.fields.results": "Results",
2324
"flowChat.builtin.fields.objective": "Objective",
2425
"flowChat.builtin.fields.state": "State",
@@ -120,6 +121,9 @@ export const semanticToolEn = {
120121
"flowChat.builtin.fields.checksPending": "Checks pending",
121122
"flowChat.builtin.fields.author": "Author",
122123
"flowChat.builtin.fields.lastOutcome": "Last transaction outcome",
124+
"flowChat.builtin.fields.card": "Card ID",
125+
"flowChat.builtin.fields.dataSource": "Data source",
126+
"flowChat.builtin.fields.visibility": "Visibility",
123127
"flowChat.builtin.states.active": "Active",
124128
"flowChat.builtin.states.running": "Running",
125129
"flowChat.builtin.states.complete": "Done",
@@ -159,13 +163,15 @@ export const semanticToolEn = {
159163
"flowChat.builtin.states.managed": "Managed worktree",
160164
"flowChat.builtin.states.permanent": "Permanent worktree",
161165
"flowChat.builtin.states.external": "External worktree",
166+
"flowChat.builtin.states.cardCreated": "Created and shown",
162167
"flowChat.builtin.rawResult": "Recorded result details",
163168
"flowChat.builtin.directChildren": "Direct child agents",
164169
"flowChat.builtin.deleteAgentScope": "Deletes the selected agents and their descendants, including their sessions and pending results. Active work is cancelled.",
165170
"flowChat.builtin.portMoved": "The requested local port was occupied. Use the actual address shown above.",
166171
"flowChat.builtin.runtimeNotified": "Open Mini App runtimes were notified to reload.",
167172
"flowChat.builtin.reviewPending": "The submission is awaiting marketplace review. Follow its status in My submissions.",
168173
"flowChat.builtin.playbookInstructions": "These are the resolved instructions. Their steps are executed through subsequent tool calls.",
174+
"flowChat.builtin.desktopCard.visible": "Shown on desktop",
169175
"flowChat.builtin.samples.goal": "Improve keyboard navigation",
170176
"flowChat.builtin.samples.analysis": "The page contains a navigation rail, a summary and a results table.",
171177
"flowChat.builtin.samples.error": "The host could not finish this operation. Recorded details remain available.",
@@ -181,7 +187,8 @@ export const semanticToolEn = {
181187
"component.FrontendWorkbenchToolCard.description": "Frontend customization",
182188
"component.MiniAppFinalizeToolCard.description": "Update Mini App",
183189
"component.MarketplacePublishToolCard.description": "Submit Mini App",
184-
"component.PlaybookToolCard.description": "Read operation guide"
190+
"component.PlaybookToolCard.description": "Read operation guide",
191+
"component.DesktopCardToolCard.description": "Desktop card"
185192
} as const;
186193

187194
export const semanticToolZhCN = {
@@ -205,6 +212,7 @@ export const semanticToolZhCN = {
205212
"flowChat.builtin.tools.PublishMiniApp": "提交小应用审核",
206213
"flowChat.builtin.tools.PublishAppearance": "提交皮肤审核",
207214
"flowChat.builtin.tools.Playbook": "读取操作流程",
215+
"flowChat.builtin.tools.DesktopCard": "小卡片",
208216
"flowChat.builtin.fields.results": "结果",
209217
"flowChat.builtin.fields.objective": "目标",
210218
"flowChat.builtin.fields.state": "状态",
@@ -306,6 +314,9 @@ export const semanticToolZhCN = {
306314
"flowChat.builtin.fields.checksPending": "待完成检查数",
307315
"flowChat.builtin.fields.author": "作者",
308316
"flowChat.builtin.fields.lastOutcome": "上次事务结果",
317+
"flowChat.builtin.fields.card": "卡片 ID",
318+
"flowChat.builtin.fields.dataSource": "数据来源",
319+
"flowChat.builtin.fields.visibility": "显示状态",
309320
"flowChat.builtin.states.active": "进行中",
310321
"flowChat.builtin.states.running": "运行中",
311322
"flowChat.builtin.states.complete": "已完成",
@@ -345,13 +356,15 @@ export const semanticToolZhCN = {
345356
"flowChat.builtin.states.managed": "托管工作树",
346357
"flowChat.builtin.states.permanent": "永久工作树",
347358
"flowChat.builtin.states.external": "外部工作树",
359+
"flowChat.builtin.states.cardCreated": "已创建并显示",
348360
"flowChat.builtin.rawResult": "原始结果详情",
349361
"flowChat.builtin.directChildren": "直属子代理",
350362
"flowChat.builtin.deleteAgentScope": "删除所选子代理及其后代的会话和待处理结果,并取消进行中的工作。",
351363
"flowChat.builtin.portMoved": "请求的本地端口已被占用,请使用上方显示的实际地址。",
352364
"flowChat.builtin.runtimeNotified": "已通知打开的小应用重新加载。",
353365
"flowChat.builtin.reviewPending": "投稿正在等待市场审核,可在“我的投稿”查看进度。",
354366
"flowChat.builtin.playbookInstructions": "这里显示的是已载入的操作步骤,实际执行由后续工具调用完成。",
367+
"flowChat.builtin.desktopCard.visible": "显示在桌面",
355368
"flowChat.builtin.samples.goal": "完善键盘导航",
356369
"flowChat.builtin.samples.analysis": "页面包含导航栏、摘要和结果表格。",
357370
"flowChat.builtin.samples.error": "主机未能完成此操作,仍可查看已记录的详情。",
@@ -367,7 +380,8 @@ export const semanticToolZhCN = {
367380
"component.FrontendWorkbenchToolCard.description": "界面定制",
368381
"component.MiniAppFinalizeToolCard.description": "更新小应用",
369382
"component.MarketplacePublishToolCard.description": "提交小应用审核",
370-
"component.PlaybookToolCard.description": "读取操作流程"
383+
"component.PlaybookToolCard.description": "读取操作流程",
384+
"component.DesktopCardToolCard.description": "小卡片"
371385
} as const;
372386

373387
export const semanticToolZhTW = {
@@ -391,6 +405,7 @@ export const semanticToolZhTW = {
391405
"flowChat.builtin.tools.PublishMiniApp": "提交小應用程式審核",
392406
"flowChat.builtin.tools.PublishAppearance": "提交外觀審核",
393407
"flowChat.builtin.tools.Playbook": "讀取操作流程",
408+
"flowChat.builtin.tools.DesktopCard": "小卡片",
394409
"flowChat.builtin.fields.results": "結果",
395410
"flowChat.builtin.fields.objective": "目標",
396411
"flowChat.builtin.fields.state": "狀態",
@@ -492,6 +507,9 @@ export const semanticToolZhTW = {
492507
"flowChat.builtin.fields.checksPending": "待完成檢查數",
493508
"flowChat.builtin.fields.author": "作者",
494509
"flowChat.builtin.fields.lastOutcome": "上次交易結果",
510+
"flowChat.builtin.fields.card": "卡片 ID",
511+
"flowChat.builtin.fields.dataSource": "資料來源",
512+
"flowChat.builtin.fields.visibility": "顯示狀態",
495513
"flowChat.builtin.states.active": "進行中",
496514
"flowChat.builtin.states.running": "執行中",
497515
"flowChat.builtin.states.complete": "已完成",
@@ -531,13 +549,15 @@ export const semanticToolZhTW = {
531549
"flowChat.builtin.states.managed": "受管理工作樹",
532550
"flowChat.builtin.states.permanent": "永久工作樹",
533551
"flowChat.builtin.states.external": "外部工作樹",
552+
"flowChat.builtin.states.cardCreated": "已建立並顯示",
534553
"flowChat.builtin.rawResult": "原始結果詳細資料",
535554
"flowChat.builtin.directChildren": "直屬子代理",
536555
"flowChat.builtin.deleteAgentScope": "刪除所選子代理及其後代的工作階段和待處理結果,並取消進行中的工作。",
537556
"flowChat.builtin.portMoved": "要求的本機連接埠已被占用,請使用上方顯示的實際位址。",
538557
"flowChat.builtin.runtimeNotified": "已通知開啟的小應用程式重新載入。",
539558
"flowChat.builtin.reviewPending": "投稿正在等待市集審核,可在「我的投稿」檢視進度。",
540559
"flowChat.builtin.playbookInstructions": "此處顯示已載入的操作步驟,實際執行由後續工具呼叫完成。",
560+
"flowChat.builtin.desktopCard.visible": "顯示在桌面",
541561
"flowChat.builtin.samples.goal": "完善鍵盤導覽",
542562
"flowChat.builtin.samples.analysis": "頁面包含導覽列、摘要與結果表格。",
543563
"flowChat.builtin.samples.error": "主機未能完成此操作,仍可檢視已記錄的詳情。",
@@ -553,5 +573,6 @@ export const semanticToolZhTW = {
553573
"component.FrontendWorkbenchToolCard.description": "介面自訂",
554574
"component.MiniAppFinalizeToolCard.description": "更新小應用程式",
555575
"component.MarketplacePublishToolCard.description": "提交小應用程式審核",
556-
"component.PlaybookToolCard.description": "讀取操作流程"
576+
"component.PlaybookToolCard.description": "讀取操作流程",
577+
"component.DesktopCardToolCard.description": "小卡片"
557578
} as const;

‎design-system/apps/design-lab/src/preview/FlowChatMockTools.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const groupForTool = {
1414
ListMCPResources: 'execution', ReadMCPResource: 'execution', ListMCPPrompts: 'execution', GetMCPPrompt: 'execution',
1515
Worktree: 'files', PortForward: 'execution', ReviewPlatform: 'collaboration', FrontendWorkbench: 'web',
1616
FinalizeMiniApp: 'web', PublishMiniApp: 'web', PublishAppearance: 'web', Playbook: 'execution',
17+
DesktopCard: 'collaboration',
1718
Read: 'files', Write: 'files', Edit: 'files', Delete: 'files', Grep: 'files', Glob: 'files', LS: 'files',
1819
GetFileDiff: 'files', view_image: 'files',
1920
ListModels: 'execution', ControlHub: 'web',

‎design-system/apps/design-lab/src/preview/SemanticToolCardPreview.tsx‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useState } from 'react';
2-
import { Target, Users, History, ScanEye, Clock, FolderSearch, GitBranch, Route, GitPullRequest, PanelsTopLeft, RefreshCw, Upload, Workflow } from 'lucide-react';
2+
import { Target, Users, History, ScanEye, Clock, FolderSearch, GitBranch, Route, GitPullRequest, PanelsTopLeft, RefreshCw, Upload, Workflow, AppWindow } from 'lucide-react';
33
import {
44
GoalToolCard, AgentRosterToolCard, SessionHistoryToolCard, ImageAnalysisToolCard, TimeToolCard,
55
McpResourceToolCard, WorktreeToolCard, PortForwardToolCard, ReviewPlatformToolCard,
66
FrontendWorkbenchToolCard, MiniAppFinalizeToolCard, MarketplacePublishToolCard, PlaybookToolCard,
7+
DesktopCardToolCard,
78
type SemanticToolCardProps,
89
} from '@openbitfun/ui/flow-chat';
910
import { toolsForComponent } from '@openbitfun/flow-chat-presentation/registry';
@@ -12,20 +13,21 @@ import type { FlowChatPreviewDefinition } from './FlowChatPreviewRegistry';
1213

1314
const views = { GoalToolCard, AgentRosterToolCard, SessionHistoryToolCard, ImageAnalysisToolCard, TimeToolCard,
1415
McpResourceToolCard, WorktreeToolCard, PortForwardToolCard, ReviewPlatformToolCard,
15-
FrontendWorkbenchToolCard, MiniAppFinalizeToolCard, MarketplacePublishToolCard, PlaybookToolCard };
16+
FrontendWorkbenchToolCard, MiniAppFinalizeToolCard, MarketplacePublishToolCard, PlaybookToolCard, DesktopCardToolCard };
1617
type Name = keyof typeof views;
1718
const icons = { GoalToolCard: Target, AgentRosterToolCard: Users, SessionHistoryToolCard: History,
1819
ImageAnalysisToolCard: ScanEye, TimeToolCard: Clock, McpResourceToolCard: FolderSearch, WorktreeToolCard: GitBranch,
1920
PortForwardToolCard: Route, ReviewPlatformToolCard: GitPullRequest, FrontendWorkbenchToolCard: PanelsTopLeft,
20-
MiniAppFinalizeToolCard: RefreshCw, MarketplacePublishToolCard: Upload, PlaybookToolCard: Workflow };
21+
MiniAppFinalizeToolCard: RefreshCw, MarketplacePublishToolCard: Upload, PlaybookToolCard: Workflow,
22+
DesktopCardToolCard: AppWindow };
2123

2224
function SemanticPreview({ component, interactive, specimen, state }: Parameters<FlowChatPreviewDefinition['render']>[0] & { component: Name }) {
2325
const { t } = useI18n();
2426
const [expanded, setExpanded] = useState(state === 'expanded' || state === 'error');
2527
const text = (key: string) => t(`flowChat.builtin.${key}` as MessageKey);
2628
const tool = specimen?.tool ?? toolsForComponent(component)[0] ?? component;
2729
const prominent = ['create_goal', 'update_goal', 'AgentDelete', 'Worktree', 'PortForward', 'ReviewPlatform',
28-
'FrontendWorkbench', 'FinalizeMiniApp', 'PublishMiniApp', 'PublishAppearance'].includes(tool);
30+
'FrontendWorkbench', 'FinalizeMiniApp', 'PublishMiniApp', 'PublishAppearance', 'DesktopCard'].includes(tool);
2931
const props: SemanticToolCardProps = {
3032
action: text(`tools.${tool}`), status: state === 'loading' ? 'running' : state === 'error' ? 'error' : 'completed',
3133
attention: prominent ? 'prominent' : 'ambient', isExpanded: expanded,
@@ -75,6 +77,11 @@ function SemanticPreview({ component, interactive, specimen, state }: Parameters
7577
case 'PlaybookToolCard':
7678
props.summary = 'Review'; props.ordered = true; props.recordsLabel = text('fields.steps'); props.notice = text('playbookInstructions');
7779
props.records = [{ key: '1', title: 'browser.snapshot' }, { key: '2', title: 'browser.read_article' }]; break;
80+
case 'DesktopCardToolCard':
81+
props.summary = 'PR #42 · checks';
82+
props.fields = [field('card', 'pr-42-checks'), field('template', 'metrics'),
83+
field('dataSource', 'https://api.github.com/repos/openbitfun/app/pulls/42'), field('visibility', text('desktopCard.visible'))];
84+
props.outcome = { label: text('states.cardCreated'), tone: 'success' }; break;
7885
}
7986
if (props.status !== 'completed') props.outcome = undefined;
8087
if (component === 'AgentRosterToolCard') return <AgentRosterToolCard {...props} deleting={tool === 'AgentDelete'} />;
@@ -99,5 +106,5 @@ export const semanticToolCardPreviews = {
99106
WorktreeToolCard: definition('WorktreeToolCard'), PortForwardToolCard: definition('PortForwardToolCard'),
100107
ReviewPlatformToolCard: definition('ReviewPlatformToolCard'), FrontendWorkbenchToolCard: definition('FrontendWorkbenchToolCard'),
101108
MiniAppFinalizeToolCard: definition('MiniAppFinalizeToolCard'), MarketplacePublishToolCard: definition('MarketplacePublishToolCard'),
102-
PlaybookToolCard: definition('PlaybookToolCard'),
109+
PlaybookToolCard: definition('PlaybookToolCard'), DesktopCardToolCard: definition('DesktopCardToolCard'),
103110
} satisfies Record<Name, FlowChatPreviewDefinition>;

‎design-system/packages/ui/src/flow-chat/tool-cards/SemanticToolCards.meta.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,9 @@ export const semanticToolCardMetas = [
8080
description: "Resolved operation guides and ordered steps, independent of execution.",
8181
props, states, tokens,
8282
},
83+
{
84+
category: "flow-chat", name: "DesktopCardToolCard", maturity: "stable",
85+
description: "Desktop card creation, visibility, refresh and preset results.",
86+
props, states, tokens,
87+
},
8388
] as const satisfies readonly ComponentMeta[];

‎design-system/packages/ui/src/flow-chat/tool-cards/SemanticToolCards.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,6 @@ export function MarketplacePublishToolCard({ appearance = false, ...props }: Sem
200200
export function PlaybookToolCard(props: SemanticToolCardProps) {
201201
return <SemanticToolCard {...props} identity="playbook" iconName="workflow" />;
202202
}
203+
export function DesktopCardToolCard(props: SemanticToolCardProps) {
204+
return <SemanticToolCard {...props} identity="desktop-card" iconName="floating-window" />;
205+
}

‎design-system/packages/ui/src/flow-chat/tool-cards/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export {
22
GoalToolCard, AgentRosterToolCard, SessionHistoryToolCard, ImageAnalysisToolCard, TimeToolCard,
33
McpResourceToolCard, WorktreeToolCard, PortForwardToolCard, ReviewPlatformToolCard,
44
FrontendWorkbenchToolCard, MiniAppFinalizeToolCard, MarketplacePublishToolCard, PlaybookToolCard,
5+
DesktopCardToolCard,
56
type SemanticToolCardProps, type SemanticToolCardAction, type SemanticToolCardRecord, type SemanticToolCardSection, type SemanticToolCardField,
67
} from "./SemanticToolCards";
78
export {

‎design-system/packages/ui/tests/registry.test.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test("registry exposes only the formal stable components", () => {
1414
"GoalToolCard", "AgentRosterToolCard", "SessionHistoryToolCard", "ImageAnalysisToolCard", "TimeToolCard",
1515
"McpResourceToolCard", "WorktreeToolCard", "PortForwardToolCard", "ReviewPlatformToolCard", "FrontendWorkbenchToolCard",
1616
"MiniAppFinalizeToolCard", "MarketplacePublishToolCard", "PlaybookToolCard",
17+
"DesktopCardToolCard",
1718
"ActionCard",
1819
"ActionItem",
1920
"ActivityItem",

0 commit comments

Comments
 (0)