wezard 2.0.1 → 2.0.3

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/web/chat.css CHANGED
@@ -18,14 +18,18 @@
18
18
  --pub: #237a55; /* 公开 */
19
19
  }
20
20
 
21
- html, body { height: 100% }
21
+ html { height: 100% }
22
22
  /* overscroll-behavior:none 阻止整页橡皮筋回弹 —— webview 里它会和内层
23
23
  .thread 抢滚动手势, 表现为"滚一下卡住/整页在弹"。 */
24
- body { overflow: hidden; overscroll-behavior: none; color: var(--ink) }
24
+ /* body 是一根竖轴: 上面 .app (两栏), 下面整页页脚 (wizard 的用量条)。 */
25
+ body {
26
+ height: 100vh; height: 100dvh; display: flex; flex-direction: column;
27
+ overflow: hidden; overscroll-behavior: none; color: var(--ink);
28
+ }
25
29
  button { font: inherit; color: inherit }
26
30
  :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
27
31
 
28
- .app { display: flex; height: 100vh; height: 100dvh }
32
+ .app { display: flex; flex: 1; min-height: 0 }
29
33
  @keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
30
34
 
31
35
  /* 名字 = 地址。点是地址的一部分, 也是这一页唯一的颜色记号。 */
@@ -39,7 +43,7 @@ button { font: inherit; color: inherit }
39
43
  display: flex; flex-direction: column; min-height: 0;
40
44
  }
41
45
 
42
- /* ── 左栏顶: 当前 role 的名片 (身份 + 关系/日程入口) ──── */
46
+ /* ── 左栏顶: 当前 role 的名片 (身份); 关系/日程入口是名片下、会话列表上的一排 ──── */
43
47
  .rolebar {
44
48
  position: relative; flex: none; padding: 16px 16px 14px; border-bottom: 1px solid var(--line);
45
49
  display: flex; flex-direction: column; gap: 8px; background: var(--card);
@@ -49,15 +53,27 @@ button { font: inherit; color: inherit }
49
53
  .rolebar .id .l { min-width: 0; display: flex; flex-direction: column; gap: 2px }
50
54
  .rolebar .id .nm { font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
51
55
  .rolebar .id .k { font-size: 11.5px; color: var(--mute) }
56
+ /* 名片上的状态: 只有执行中带颜色与呼吸, 空闲 / 已关闭是一个安静的词。 */
57
+ .rolebar .st { margin-left: 8px; white-space: nowrap }
58
+ .rolebar .st::before {
59
+ content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 4px;
60
+ border-radius: 50%; background: #b1bac4; vertical-align: 1px;
61
+ }
62
+ .rolebar .st.run { color: #1a7f37 }
63
+ .rolebar .st.run::before { background: #1a7f37; animation: pulse 1.4s infinite }
64
+ .rolebar .st.off { color: var(--faint) }
65
+ .rolebar .st.off::before { background: transparent; box-shadow: inset 0 0 0 1.5px #b1bac4 }
52
66
  .rolebar .job { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink); opacity: .8 }
53
67
  .rolebar .facts { display: flex; gap: 6px 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--mute) }
54
68
  .rolebar .facts span { white-space: nowrap }
55
69
  .rolebar .go { cursor: pointer; color: var(--accent) }
56
70
  .rolebar .go:hover { text-decoration: underline }
57
- .rolebar .acts { display: flex; gap: 6px; flex-wrap: wrap; align-items: center }
58
- .rolebar .acts:empty { display: none }
71
+ .acts { flex: none; display: flex; gap: 6px; padding: 8px 12px; border-bottom: 1px solid var(--line) }
72
+ .acts:empty { display: none }
73
+ /* 旧外壳 (daemon 未重启) 里它还在名片内 —— 那里不需要自己的内边距与分隔线。 */
74
+ .rolebar .acts { padding: 0; border: 0 }
59
75
  .bd {
60
- font-size: 11px; line-height: 18px; padding: 0 8px; border: 0; border-radius: 9px; cursor: pointer;
76
+ flex: 1; font-size: 12.5px; line-height: 28px; padding: 0 10px; border: 0; border-radius: 8px; cursor: pointer;
61
77
  background: #f1f3f6; color: var(--mute); white-space: nowrap;
62
78
  }
63
79
  .bd:hover { color: var(--accent) }
@@ -99,36 +115,35 @@ button { font: inherit; color: inherit }
99
115
  .sp-it.all { border-bottom: 1px solid var(--line); border-radius: 6px 6px 0 0; margin-bottom: 3px }
100
116
  .sp-it.all .id { font-family: inherit }
101
117
 
102
- /* 左栏底: session 切换 + 用量, 都是轮次的事 —— 与顶上的身份分开, 钉在会话列表下面。 */
103
- .sidefoot {
104
- flex: none; border-top: 1px solid var(--line); padding: 10px 12px 12px;
105
- display: flex; flex-direction: column; gap: 8px; background: var(--paper);
106
- }
107
- .sidefoot[hidden] { display: none }
108
- #rb-sess:empty, #rb-prof:empty { display: none }
118
+ /* 左栏底: session 切换 —— 轮次的事, 与顶上的身份分开, 钉在会话列表下面。 */
119
+ .sidefoot { flex: none; border-top: 1px solid var(--line); padding: 10px 12px; background: var(--paper) }
109
120
  /* 在底部, 浮层往上开。 */
110
121
  .sidefoot .sp-list { top: auto; bottom: calc(100% + 4px); transform: translateY(4px) }
111
122
  .sidefoot .sp.open .sp-list { transform: none }
112
123
 
113
- /* profile: 这个 role 自己跑过的轮次的总账 —— 平铺在左栏底, 不套卡片。 */
114
- .prof { font-family: ui-monospace, Menlo, monospace }
115
- .prof .hd { display: flex; align-items: center; gap: 8px; font-size: 11.5px; margin-bottom: 6px }
116
- .prof .hd .lb { font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .4px; font-family: system-ui, sans-serif }
117
- .prof .model {
118
- margin-left: auto; color: var(--mute);
119
- max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
120
- }
121
- .prof .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px 4px }
122
- .prof .kv { display: flex; flex-direction: column; align-items: flex-start; min-width: 0 }
123
- .prof .kv .v { font-size: 13px; font-weight: 700; color: #1f2328; font-variant-numeric: tabular-nums; white-space: nowrap }
124
- .prof .kv .k { font-size: 9.5px; color: #8c959f; text-transform: uppercase; letter-spacing: .4px }
125
- .prof .io { margin-top: 8px; display: flex; flex-direction: column; gap: 6px }
126
- .prof .bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: #eaeef2 }
127
- .prof .bar .seg { height: 100% }
128
- .prof .leg { display: flex; gap: 4px 9px; flex-wrap: wrap }
129
- .prof .lg { display: flex; align-items: center; gap: 4px; font-size: 10.5px; color: #8c959f }
130
- .prof .lg i { width: 8px; height: 8px; border-radius: 2px; flex: none }
131
- .prof .lg b { color: #1f2328; font-weight: 700; font-variant-numeric: tabular-nums }
124
+ /* ── 用量条: 一组轮次的总账 ─────────────────────────────────────────
125
+ 一个组件两处挂: 整页页脚 (wizard 的总账) / 聊天窗口底 (人与某个 wizard 这段往来的账)。
126
+ 宽屏一行排完: 标签 · 指标 · I/O 条 + 图例 · 模型。每一组自身不折行, 一行排不下时
127
+ 整组落到下一行 —— 窄屏自然变成两三行, 不需要另一套结构。 */
128
+ .usage {
129
+ flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 20px;
130
+ padding: 7px 20px; border-top: 1px solid var(--line); background: var(--paper);
131
+ font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--mute);
132
+ font-variant-numeric: tabular-nums;
133
+ }
134
+ .usage b { font-weight: 700; color: var(--ink) }
135
+ .usage .u-lb { font: 10px system-ui, sans-serif; color: var(--faint); letter-spacing: .4px }
136
+ .usage .u-kvs { display: flex; gap: 4px 16px }
137
+ .usage .kv { white-space: nowrap; font-size: 9.5px; color: var(--faint); text-transform: uppercase; letter-spacing: .4px }
138
+ .usage .kv b { font-size: 12.5px; margin-right: 4px; letter-spacing: 0; text-transform: none }
139
+ .usage .u-io { display: flex; align-items: center; gap: 12px; min-width: 0 }
140
+ .usage .bar { flex: none; width: 140px; display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--line) }
141
+ .usage .bar .seg { height: 100% }
142
+ .usage .leg { display: flex; gap: 4px 12px }
143
+ .usage .lg { display: flex; align-items: center; gap: 4px; white-space: nowrap }
144
+ .usage .lg i { width: 8px; height: 8px; border-radius: 2px; flex: none }
145
+ .usage .lg b { margin-left: 1px }
146
+ .usage .u-model { margin-left: auto; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
132
147
 
133
148
  /* 群聊头像 = 参与者头像拼图: 1 格居中, 2 格左右, 3/4 格田字。 */
134
149
  .mosaic {
@@ -142,13 +157,13 @@ button { font: inherit; color: inherit }
142
157
  .mosaic.n3, .mosaic.n4 { grid-template: 1fr 1fr / 1fr 1fr }
143
158
  .mosaic.n3 i:first-child { grid-row: span 2 }
144
159
 
145
- .convs { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 8px 16px }
160
+ .convs { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 8px 16px }
146
161
  .convs h2 {
147
162
  margin: 14px 8px 4px; font-size: 12px; font-weight: 600; color: var(--mute);
148
163
  display: flex; align-items: baseline; gap: 6px;
149
164
  }
165
+ .convs h2:first-child { margin-top: 6px }
150
166
  .convs h2 span { font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums }
151
- .convs .none { padding: 6px 10px; font-size: 12px; color: var(--faint) }
152
167
 
153
168
  .ci {
154
169
  display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left; overflow: hidden;
@@ -167,12 +182,14 @@ button { font: inherit; color: inherit }
167
182
  .ci .pv { font-size: 12px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
168
183
  .ci .pv:empty { display: none }
169
184
  .ci .tag { font-size: 10.5px; border-radius: 4px; padding: 0 4px; flex: none }
170
- /* 选中的 role 项上的换视角开关。 */
171
- .sw {
172
- flex: none; align-self: center; display: inline-grid; place-items: center;
173
- width: 20px; height: 20px; border-radius: 5px; color: var(--accent); cursor: pointer;
174
- }
175
- .sw:hover { background: #2f55c91a }
185
+ /* 头像与名字是进入那个 role 视角的入口 —— 侧栏项、会话头、消息行同一种读法。
186
+ 它们嵌在整行那颗按钮里, 所以悬停态必须压过行: 指到入口上时行自己的悬停底色
187
+ 让位 (:has), 否则读起来像是要选中这一行。z-index 保证没有兄弟盖住命中区。 */
188
+ .nm.go, .av.go { position: relative; z-index: 1; cursor: pointer }
189
+ .nm.go:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 2px }
190
+ span.av.go { border-radius: 8px; transition: background .12s, box-shadow .12s }
191
+ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
192
+ .ci:not(.on):has(.go:hover), .si:not(.on):has(.go:hover) { background: transparent }
176
193
  .ci .tag.priv { color: var(--priv); background: #9a5b1014 }
177
194
 
178
195
  /* 群里的其他 role —— 挂在群下, 与会话项同一种读法 (名字 · 时刻 / 最近一句), 只压一档。
@@ -192,7 +209,15 @@ button { font: inherit; color: inherit }
192
209
  .si .ts { margin-left: auto; flex: none; font-size: 10.5px; color: var(--faint); font-variant-numeric: tabular-nums }
193
210
  .si .pv { display: block; font-size: 11.5px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
194
211
  .si .pv:empty { display: none }
195
- .si.quiet .t, .si.quiet > .av { opacity: .55 }
212
+
213
+ /* 执行中的 wizard: 头像角上一盏呼吸灯 (同关系图的 .wav .live)。 */
214
+ .ci > .av, .si > .av { position: relative }
215
+ .ci > .av .live, .si > .av .live {
216
+ position: absolute; right: 1px; bottom: -3px; width: 9px; height: 9px;
217
+ border-radius: 50%; background: #1a7f37; border: 2px solid #fff;
218
+ animation: pulse 1.4s infinite;
219
+ }
220
+ .si > .av .live { right: -1px; width: 8px; height: 8px }
196
221
 
197
222
  /* ── 右栏头: 这个群聊 / 私聊是什么 ───────────────────────────────── */
198
223
  .main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--card) }
@@ -266,11 +291,20 @@ button { font: inherit; color: inherit }
266
291
  .mrow.mine .mb .bubble, .mrow.mine .mb .typing, .mrow.mine .mb .stats { background: transparent; border-color: var(--mine-line) }
267
292
  .mrow.mine .mb .bubble.user, .mrow.mine .mb .bubble.approval,
268
293
  .mrow.mine .mb .md-body code, .mrow.mine .mb .md-body pre,
269
- .mrow.mine .mb .tile, .mrow.mine .mb details > summary,
294
+ .mrow.mine .mb .tile, .mrow.mine .mb details:not(.tool-call) > summary,
295
+ .mrow.mine .mb .tool-body section > h2, .mrow.mine .mb .diff-meta,
270
296
  .mrow.mine .mb .tool-call > summary:hover { background: var(--mine-soft); border-color: var(--mine-line) }
271
297
  .mrow.mine .mb .md-body pre code { background: transparent }
298
+ /* 展开的工具正文 (command / diff / 文件内容) 与嵌在父轮里的 subagent 卡片都是裸
299
+ section, 吃的是 TURN_CSS 的白底 —— 同样收回气泡底色; subagent 的绿色左边线留着。 */
300
+ .mrow.mine .mb .tool-body section { background: transparent; border-color: var(--mine-line) }
301
+ .mrow.mine .mb .turn-group .turn-group { background: transparent; box-shadow: none; border-color: var(--mine-line) }
302
+ .mrow.mine .mb .turn-group .turn-group.subagent { border-left-color: #1a7f3733 }
272
303
  .mrow.mine .mb .bubble details, .mrow.mine .mb .tg-head { border-color: var(--mine-line) }
273
304
  .mrow.mine .mb .tool-body { border-left-color: var(--mine-line) }
305
+ /* 工具正文是展开时才取的 (chat.js loadTool) —— 空壳期间说一句在干什么。 */
306
+ .tool-body[data-lazy-turn]:empty::before { content: "加载中…"; color: #8c959f; font-size: 12px }
307
+ .tool-body[data-lazy-turn][data-err]:empty::before { content: "加载失败 · 收起再展开重试"; color: #cf222e }
274
308
  .mrow.mine .mb .io-bar { background: var(--mine-soft) }
275
309
 
276
310
  /* 气泡对面那片空白 = 换视角的门。平时不可见, 悬停才露出要去谁那里。 */
@@ -293,7 +327,7 @@ button { font: inherit; color: inherit }
293
327
  .flip:hover, .flip:focus-visible { background: #2f55c90d; color: var(--accent) }
294
328
  .flip[disabled] { cursor: default; background: transparent !important; color: transparent !important }
295
329
  .mwho .av.go { cursor: pointer }
296
- .mwho .av.go:hover { border-color: var(--accent) }
330
+ .mwho .av.go:hover { border-color: var(--accent); background: #2f55c914 }
297
331
 
298
332
  .mrow.mark { justify-content: center }
299
333
  .mrow.mark > * { flex: 1; max-width: 520px }
@@ -376,6 +410,11 @@ button { font: inherit; color: inherit }
376
410
  .flip { min-width: 16px; padding: 0 4px; font-size: 0 }
377
411
  .turn-group { padding: 12px }
378
412
  .thread { padding-bottom: calc(12px + env(safe-area-inset-bottom)) }
413
+ .usage { padding: 8px 12px; gap: 6px 14px }
414
+ .usage .u-kvs, .usage .leg { flex-wrap: wrap }
415
+ .usage .u-io { flex: 1 1 100%; flex-wrap: wrap; gap: 6px 12px }
416
+ .usage .bar { flex: 1 1 100%; width: auto }
417
+ .usage.page { padding-bottom: calc(8px + env(safe-area-inset-bottom)) }
379
418
  }
380
419
 
381
420
  /* UA 的 [hidden] 规则和 `.gbar{display:flex}` 这类类选择器同权重, 而作者样式