@zmzai/theme 0.5.4 → 0.5.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zmzai/theme",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "zmzai 全品牌设计系统 — Radix UI + framer-motion + Tailwind v4 + MiSans",
Binary file
@@ -57,6 +57,7 @@ export * from "./markdown";
57
57
  export * from "./markdown";
58
58
  export * from "./diff-view";
59
59
  export * from "./tool-card";
60
+ export * from "./subtask";
60
61
  export * from "./todo-checklist";
61
62
  export * from "./permission-card";
62
63
 
@@ -0,0 +1,36 @@
1
+ "use client";
2
+
3
+ import "./subtask.css";
4
+
5
+ import { Badge } from "../badge/Badge";
6
+ import { Icon } from "../icon/Icon";
7
+
8
+ export interface SubtaskPartProps {
9
+ /** 子任务描述;缺省时回退显示 agent 名 */
10
+ description?: string;
11
+ /** 执行该子任务的智能体名 */
12
+ agent?: string;
13
+ /** 子任务 prompt(mono 小字显示) */
14
+ prompt?: string;
15
+ }
16
+
17
+ /**
18
+ * SubtaskPart — 执行树中的子任务行(分支线样式与 ToolCard 一致)。
19
+ *
20
+ * 上下文增强(执行树 ::before 分支线)依赖消费端容器留出左侧空间,
21
+ * 与 ToolCard 的执行树用法相同。
22
+ */
23
+ export function SubtaskPart({ description, agent, prompt }: SubtaskPartProps) {
24
+ return (
25
+ <div className="subtask-row">
26
+ <span className="subtask-icon" aria-hidden>
27
+ <Icon name="chevron-down" size={12} />
28
+ </span>
29
+ <span className="subtask-copy">
30
+ <strong>{description || agent}</strong>
31
+ {prompt ? <small>{prompt}</small> : null}
32
+ </span>
33
+ <Badge variant="outline" size="sm">子任务</Badge>
34
+ </div>
35
+ );
36
+ }
@@ -0,0 +1 @@
1
+ export * from "./SubtaskPart";
@@ -0,0 +1,11 @@
1
+ /* SubtaskPart — 执行树中的子任务行。token 依赖消费端 @theme
2
+ (--color-line、--color-accent、--color-muted、--font-mono)。
3
+ 执行树分支线(::before)等上下文增强由消费端自己的 CSS 叠加。 */
4
+
5
+ .subtask-row { position: relative; display: flex; align-items: center; gap: 0.5rem; min-height: 2.15rem; padding: 0.38rem 0.4rem; background: transparent; }
6
+ /* 执行树分支线(挂在左侧时间轴上;独立使用时容器需留出左侧空间) */
7
+ .subtask-row::before { position: absolute; top: 1.08rem; left: -0.81rem; width: 0.81rem; height: 1px; background: var(--color-line); content: ""; }
8
+ .subtask-icon { display: grid; width: 1rem; height: 1rem; place-items: center; color: var(--color-accent); }
9
+ .subtask-copy { display: grid; min-width: 0; flex: 1; gap: 0.1rem; }
10
+ .subtask-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; font-weight: 600; }
11
+ .subtask-copy small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-muted); font-family: var(--font-mono); font-size: 0.6rem; }
@@ -59,7 +59,8 @@ export function ToolCard({ call, sessionIdle = false }: { call: ToolCall; sessio
59
59
  /**
60
60
  * ToolGroup — 连续工具调用的折叠组(G1 防淹没)。
61
61
  *
62
- * 运行中/有失败/单条时自动展开;多条完成时折叠为一条摘要行。
62
+ * 仅运行中自动展开;失败/单条/历史组一律折叠为一条可点击的摘要行,
63
+ * 避免长会话里"运行了 1 个工具"头 + 展开卡的双倍瀑布。
63
64
  *
64
65
  * @example
65
66
  * <ToolGroup calls={toolCalls} sessionIdle={idle} />
@@ -69,9 +70,17 @@ export function ToolGroup({ calls, sessionIdle = false }: { calls: ToolCall[]; s
69
70
  const running = calls.filter((c) => c.state.status === "running" || c.state.status === "pending");
70
71
  const failed = calls.filter((c) => c.state.status === "error" || (sessionIdle && (c.state.status === "running" || c.state.status === "pending")));
71
72
  const done = calls.filter((c) => c.state.status === "completed");
72
- const autoExpand = running.length > 0 || failed.length > 0 || calls.length <= 1;
73
+ const autoExpand = running.length > 0;
73
74
  const open = expanded || autoExpand;
74
75
  const glyph = failed.length > 0 ? "cross" : running.length > 0 ? "chevron-down" : "check";
76
+ const single = calls.length === 1 ? calls[0] : undefined;
77
+ const singleTitle = single
78
+ ? single.state.status === "completed"
79
+ ? (single.state.title ?? single.tool)
80
+ : single.state.status === "error"
81
+ ? single.state.error
82
+ : single.tool
83
+ : null;
75
84
  const summary = [
76
85
  running.length > 0 && `${running.length} 个进行中`,
77
86
  failed.length > 0 && `${failed.length} 个失败`,
@@ -81,8 +90,8 @@ export function ToolGroup({ calls, sessionIdle = false }: { calls: ToolCall[]; s
81
90
  <div className="zmz-tool-group">
82
91
  <button type="button" className="zmz-tool-group-trigger" aria-expanded={open} onClick={() => setExpanded((value) => !value)} disabled={autoExpand}>
83
92
  <span className="tool-card-glyph" aria-hidden><Icon name={glyph} size={12} /></span>
84
- <span className="zmz-tool-group-label">运行了 {calls.length} 个工具</span>
85
- {!autoExpand && <small>{summary}</small>}
93
+ <span className="zmz-tool-group-label">{single ? singleTitle : `运行了 ${calls.length} 个工具`}</span>
94
+ <small>{single ? (single.state.status === "completed" ? "完成" : single.state.status === "error" ? "失败" : "进行中") : summary}</small>
86
95
  <Icon name="chevron-down" size={12} className={open ? "tool-card-chevron open" : "tool-card-chevron"} />
87
96
  </button>
88
97
  {open && (