wezard 2.0.0 → 2.0.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CLAUDE.md +7 -8
- package/README.md +20 -32
- package/cli/wezard.sh +0 -62
- package/config.example.jsonc +3 -9
- package/dist/cli/init.js +12 -21
- package/dist/cli/init.js.map +1 -1
- package/dist/daemon/approval.js +2 -4
- package/dist/daemon/approval.js.map +1 -1
- package/dist/daemon/cc-session.js +136 -0
- package/dist/daemon/cc-session.js.map +1 -0
- package/dist/daemon/detail.js +2 -3
- package/dist/daemon/detail.js.map +1 -1
- package/dist/daemon/inbound.js +90 -110
- package/dist/daemon/inbound.js.map +1 -1
- package/dist/daemon/index.js +130 -111
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/memory-steward.js +82 -0
- package/dist/daemon/memory-steward.js.map +1 -0
- package/dist/daemon/mirror-bridge.js +201 -62
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/daemon/session-name.js +4 -27
- package/dist/daemon/session-name.js.map +1 -1
- package/dist/daemon/spawn-tmux.js +35 -13
- package/dist/daemon/spawn-tmux.js.map +1 -1
- package/dist/daemon/wizard-memory.js +21 -26
- package/dist/daemon/wizard-memory.js.map +1 -1
- package/dist/daemon/wizard.js +54 -11
- package/dist/daemon/wizard.js.map +1 -1
- package/dist/mcp/server.js +63 -153
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/chat-http.js +44 -16
- package/dist/shared/chat-http.js.map +1 -1
- package/dist/shared/chat-render.js +10 -8
- package/dist/shared/chat-render.js.map +1 -1
- package/dist/shared/cli-backends.js +2 -7
- package/dist/shared/cli-backends.js.map +1 -1
- package/dist/shared/config.js +10 -12
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/detail-render.js +35 -16
- package/dist/shared/detail-render.js.map +1 -1
- package/dist/shared/detail-store.js +14 -3
- package/dist/shared/detail-store.js.map +1 -1
- package/dist/shared/role-render.js +4 -1
- package/dist/shared/role-render.js.map +1 -1
- package/dist/shared/role-view.js +49 -11
- package/dist/shared/role-view.js.map +1 -1
- package/dist/shared/world.js +11 -1
- package/dist/shared/world.js.map +1 -1
- package/hooks/pre-tool-use.sh +4 -4
- package/package.json +1 -2
- package/web/chat.css +103 -58
- package/web/chat.js +153 -82
- package/commands/wrc.md +0 -7
- package/dist/daemon/cc-bridge.js +0 -183
- package/dist/daemon/cc-bridge.js.map +0 -1
- package/dist/daemon/sessions.js +0 -4
- package/dist/daemon/sessions.js.map +0 -1
package/hooks/pre-tool-use.sh
CHANGED
|
@@ -190,7 +190,7 @@ if [[ "$TOOL_NAME" == "ExitPlanMode" ]]; then
|
|
|
190
190
|
emit "allow" "ExitPlanMode passthrough"
|
|
191
191
|
fi
|
|
192
192
|
|
|
193
|
-
# wezard 自家 MCP 工具全部走 loopback 到本 daemon,
|
|
193
|
+
# wezard 自家 MCP 工具全部走 loopback 到本 daemon, 自审会把首次绑定卡死
|
|
194
194
|
# (还没 defaultChat, 卡片无处可推 → 鸡生蛋), 直接放行。
|
|
195
195
|
# 命名两条路径:
|
|
196
196
|
# 1. cli/sync.ts (legacy claude-internal): mcp__wezard__<tool>
|
|
@@ -200,8 +200,8 @@ if [[ "$TOOL_NAME" == mcp__*wezard__* ]]; then
|
|
|
200
200
|
emit "allow" "wezard mcp self-call bypass"
|
|
201
201
|
fi
|
|
202
202
|
|
|
203
|
-
# wezard 自家 Skill (slash commands like /
|
|
204
|
-
# tool_input.skill 形如 "wezard:
|
|
203
|
+
# wezard 自家 Skill (slash commands like /wezard:audit) 也是本地插件代码, 无须审批。
|
|
204
|
+
# tool_input.skill 形如 "wezard:audit"; plugin 命名空间用冒号分隔。
|
|
205
205
|
if [[ "$TOOL_NAME" == "Skill" ]]; then
|
|
206
206
|
SKILL_NAME=$(printf '%s' "$TOOL_INPUT" | jq -r '.skill // ""')
|
|
207
207
|
if [[ "$SKILL_NAME" == wezard:* ]]; then
|
|
@@ -216,7 +216,7 @@ if [[ "$TOOL_NAME" == "Bash" ]]; then
|
|
|
216
216
|
&& [[ ! "$CMD" =~ [\;\|\&\>\<\`\$\(] ]]; then
|
|
217
217
|
emit "allow" "read-only bypass"
|
|
218
218
|
fi
|
|
219
|
-
# wezard CLI 同理: /
|
|
219
|
+
# wezard CLI 同理: /wezard:audit /wezard:update 这些 slash command 的 ! bash 都打到本 daemon,
|
|
220
220
|
# 自己审自己没意义, 也避免首次绑定时无处推卡。
|
|
221
221
|
if [[ "$CMD" =~ (^|/|[[:space:]])wezard(\.sh)?([[:space:]]|$) ]]; then
|
|
222
222
|
emit "allow" "wezard self-call bypass"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wezard",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Bridge Claude Code and WeCom: PreToolUse approval cards + bidirectional tmux session mirror with image paste",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"systemd/wezard.service.template",
|
|
62
62
|
"systemd/wezard-svr.service.template",
|
|
63
63
|
"config.example.jsonc",
|
|
64
|
-
"commands/wrc.md",
|
|
65
64
|
"commands/audit.md",
|
|
66
65
|
"commands/update.md",
|
|
67
66
|
"README.md",
|
package/web/chat.css
CHANGED
|
@@ -18,20 +18,24 @@
|
|
|
18
18
|
--pub: #237a55; /* 公开 */
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
html
|
|
21
|
+
html { height: 100% }
|
|
22
22
|
/* overscroll-behavior:none 阻止整页橡皮筋回弹 —— webview 里它会和内层
|
|
23
23
|
.thread 抢滚动手势, 表现为"滚一下卡住/整页在弹"。 */
|
|
24
|
-
body
|
|
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;
|
|
32
|
+
.app { display: flex; flex: 1; min-height: 0 }
|
|
29
33
|
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
|
|
30
34
|
|
|
31
35
|
/* 名字 = 地址。点是地址的一部分, 也是这一页唯一的颜色记号。 */
|
|
32
36
|
.nm { font-weight: 600 }
|
|
33
37
|
.nm::before { content: "."; color: var(--accent); font-weight: 700 }
|
|
34
|
-
.nm.human::before, .nm.task::before, .nm.chat::before { content: none }
|
|
38
|
+
.nm.human::before, .nm.task::before, .nm.system::before, .nm.chat::before { content: none }
|
|
35
39
|
|
|
36
40
|
/* ── 侧栏: 我 + 会话 ─────────────────────────────────────────────── */
|
|
37
41
|
.side {
|
|
@@ -44,19 +48,35 @@ button { font: inherit; color: inherit }
|
|
|
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);
|
|
46
50
|
}
|
|
47
|
-
.rolebar .
|
|
48
|
-
.rolebar .id { display: flex; gap: 10px; align-items: center; min-width: 0; padding-right: 14px }
|
|
51
|
+
.rolebar .id { display: flex; gap: 10px; align-items: center; min-width: 0 }
|
|
49
52
|
.rolebar .id .av { font-size: 26px; line-height: 1; flex: none }
|
|
50
53
|
.rolebar .id .l { min-width: 0; display: flex; flex-direction: column; gap: 2px }
|
|
51
54
|
.rolebar .id .nm { font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
52
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 }
|
|
53
66
|
.rolebar .job { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink); opacity: .8 }
|
|
54
67
|
.rolebar .facts { display: flex; gap: 6px 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--mute) }
|
|
55
68
|
.rolebar .facts span { white-space: nowrap }
|
|
56
|
-
.rolebar .
|
|
57
|
-
.rolebar .
|
|
69
|
+
.rolebar .go { cursor: pointer; color: var(--accent) }
|
|
70
|
+
.rolebar .go:hover { text-decoration: underline }
|
|
58
71
|
.rolebar .acts { display: flex; gap: 6px; flex-wrap: wrap; align-items: center }
|
|
59
72
|
.rolebar .acts:empty { display: none }
|
|
73
|
+
.bd {
|
|
74
|
+
font-size: 11px; line-height: 18px; padding: 0 8px; border: 0; border-radius: 9px; cursor: pointer;
|
|
75
|
+
background: #f1f3f6; color: var(--mute); white-space: nowrap;
|
|
76
|
+
}
|
|
77
|
+
.bd:hover { color: var(--accent) }
|
|
78
|
+
.bd.on { background: var(--mine-soft); color: var(--accent) }
|
|
79
|
+
.bd b { font-weight: 600; margin-left: 4px; font-variant-numeric: tabular-nums }
|
|
60
80
|
/* session 切换: 按钮 + 浮层列表, 取代原生 <select>。 */
|
|
61
81
|
.sp { position: relative; flex: 1 1 100%; min-width: 0 }
|
|
62
82
|
.sp-btn {
|
|
@@ -93,39 +113,35 @@ button { font: inherit; color: inherit }
|
|
|
93
113
|
.sp-it.all { border-bottom: 1px solid var(--line); border-radius: 6px 6px 0 0; margin-bottom: 3px }
|
|
94
114
|
.sp-it.all .id { font-family: inherit }
|
|
95
115
|
|
|
96
|
-
/* 左栏底: session 切换
|
|
97
|
-
.sidefoot {
|
|
98
|
-
flex: none; border-top: 1px solid var(--line); padding: 10px 12px 12px;
|
|
99
|
-
display: flex; flex-direction: column; gap: 8px; background: var(--paper);
|
|
100
|
-
}
|
|
101
|
-
.sidefoot[hidden] { display: none }
|
|
102
|
-
#rb-sess:empty, #rb-prof:empty { display: none }
|
|
116
|
+
/* 左栏底: session 切换 —— 轮次的事, 与顶上的身份分开, 钉在会话列表下面。 */
|
|
117
|
+
.sidefoot { flex: none; border-top: 1px solid var(--line); padding: 10px 12px; background: var(--paper) }
|
|
103
118
|
/* 在底部, 浮层往上开。 */
|
|
104
119
|
.sidefoot .sp-list { top: auto; bottom: calc(100% + 4px); transform: translateY(4px) }
|
|
105
120
|
.sidefoot .sp.open .sp-list { transform: none }
|
|
106
121
|
|
|
107
|
-
/*
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.
|
|
118
|
-
.
|
|
119
|
-
.
|
|
120
|
-
.
|
|
121
|
-
.
|
|
122
|
-
.
|
|
123
|
-
.
|
|
124
|
-
.
|
|
125
|
-
.
|
|
126
|
-
.
|
|
127
|
-
.
|
|
128
|
-
.
|
|
122
|
+
/* ── 用量条: 一组轮次的总账 ─────────────────────────────────────────
|
|
123
|
+
一个组件两处挂: 整页页脚 (wizard 的总账) / 聊天窗口底 (人与某个 wizard 这段往来的账)。
|
|
124
|
+
宽屏一行排完: 标签 · 指标 · I/O 条 + 图例 · 模型。每一组自身不折行, 一行排不下时
|
|
125
|
+
整组落到下一行 —— 窄屏自然变成两三行, 不需要另一套结构。 */
|
|
126
|
+
.usage {
|
|
127
|
+
flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 20px;
|
|
128
|
+
padding: 7px 20px; border-top: 1px solid var(--line); background: var(--paper);
|
|
129
|
+
font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--mute);
|
|
130
|
+
font-variant-numeric: tabular-nums;
|
|
131
|
+
}
|
|
132
|
+
.usage b { font-weight: 700; color: var(--ink) }
|
|
133
|
+
.usage .u-lb { font: 10px system-ui, sans-serif; color: var(--faint); letter-spacing: .4px }
|
|
134
|
+
.usage .u-kvs { display: flex; gap: 4px 16px }
|
|
135
|
+
.usage .kv { white-space: nowrap; font-size: 9.5px; color: var(--faint); text-transform: uppercase; letter-spacing: .4px }
|
|
136
|
+
.usage .kv b { font-size: 12.5px; margin-right: 4px; letter-spacing: 0; text-transform: none }
|
|
137
|
+
.usage .u-io { display: flex; align-items: center; gap: 12px; min-width: 0 }
|
|
138
|
+
.usage .bar { flex: none; width: 140px; display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--line) }
|
|
139
|
+
.usage .bar .seg { height: 100% }
|
|
140
|
+
.usage .leg { display: flex; gap: 4px 12px }
|
|
141
|
+
.usage .lg { display: flex; align-items: center; gap: 4px; white-space: nowrap }
|
|
142
|
+
.usage .lg i { width: 8px; height: 8px; border-radius: 2px; flex: none }
|
|
143
|
+
.usage .lg b { margin-left: 1px }
|
|
144
|
+
.usage .u-model { margin-left: auto; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
129
145
|
|
|
130
146
|
/* 群聊头像 = 参与者头像拼图: 1 格居中, 2 格左右, 3/4 格田字。 */
|
|
131
147
|
.mosaic {
|
|
@@ -145,7 +161,6 @@ button { font: inherit; color: inherit }
|
|
|
145
161
|
display: flex; align-items: baseline; gap: 6px;
|
|
146
162
|
}
|
|
147
163
|
.convs h2 span { font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
148
|
-
.convs .none { padding: 6px 10px; font-size: 12px; color: var(--faint) }
|
|
149
164
|
|
|
150
165
|
.ci {
|
|
151
166
|
display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left; overflow: hidden;
|
|
@@ -164,23 +179,43 @@ button { font: inherit; color: inherit }
|
|
|
164
179
|
.ci .pv { font-size: 12px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
165
180
|
.ci .pv:empty { display: none }
|
|
166
181
|
.ci .tag { font-size: 10.5px; border-radius: 4px; padding: 0 4px; flex: none }
|
|
182
|
+
/* 选中的 role 项上的换视角开关。 */
|
|
183
|
+
.sw {
|
|
184
|
+
flex: none; align-self: center; display: inline-grid; place-items: center;
|
|
185
|
+
width: 20px; height: 20px; border-radius: 5px; color: var(--accent); cursor: pointer;
|
|
186
|
+
}
|
|
187
|
+
.sw:hover { background: #2f55c91a }
|
|
167
188
|
.ci .tag.priv { color: var(--priv); background: #9a5b1014 }
|
|
168
189
|
|
|
169
|
-
/* 群里的其他 role ——
|
|
170
|
-
|
|
190
|
+
/* 群里的其他 role —— 挂在群下, 与会话项同一种读法 (名字 · 时刻 / 最近一句), 只压一档。
|
|
191
|
+
点开是「我与它在这个群里」的往来。 */
|
|
192
|
+
.subs { margin: 0 0 6px 16px; border-left: 1px solid var(--line); padding-left: 2px }
|
|
171
193
|
.si {
|
|
172
|
-
display: flex; align-items: center; gap:
|
|
173
|
-
padding:
|
|
174
|
-
font-size: 12.5px; color: var(--ink);
|
|
194
|
+
display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; overflow: hidden;
|
|
195
|
+
padding: 5px 8px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; color: var(--ink);
|
|
175
196
|
}
|
|
176
197
|
.si:hover { background: #f4f6f9 }
|
|
177
|
-
.si.on { background: #eaf0fc
|
|
178
|
-
.si .
|
|
179
|
-
.si .
|
|
180
|
-
.si.
|
|
198
|
+
.si.on { background: #eaf0fc }
|
|
199
|
+
.si > .av { font-size: 17px; line-height: 1; flex: none; width: 24px; text-align: center }
|
|
200
|
+
.si .b { min-width: 0; flex: 1; overflow: hidden }
|
|
201
|
+
.si .l1 { display: flex; align-items: baseline; gap: 6px }
|
|
202
|
+
.si .t { font-size: 12.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
203
|
+
.si.on .t { color: var(--accent) }
|
|
204
|
+
.si .ts { margin-left: auto; flex: none; font-size: 10.5px; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
205
|
+
.si .pv { display: block; font-size: 11.5px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
206
|
+
.si .pv:empty { display: none }
|
|
207
|
+
|
|
208
|
+
/* 执行中的 wizard: 头像角上一盏呼吸灯 (同关系图的 .wav .live)。 */
|
|
209
|
+
.ci > .av, .si > .av { position: relative }
|
|
210
|
+
.ci > .av .live, .si > .av .live {
|
|
211
|
+
position: absolute; right: 1px; bottom: -3px; width: 9px; height: 9px;
|
|
212
|
+
border-radius: 50%; background: #1a7f37; border: 2px solid #fff;
|
|
213
|
+
animation: pulse 1.4s infinite;
|
|
214
|
+
}
|
|
215
|
+
.si > .av .live { right: -1px; width: 8px; height: 8px }
|
|
181
216
|
|
|
182
217
|
/* ── 右栏头: 这个群聊 / 私聊是什么 ───────────────────────────────── */
|
|
183
|
-
.main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--
|
|
218
|
+
.main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--card) }
|
|
184
219
|
.chathead {
|
|
185
220
|
flex: none; display: flex; align-items: center; gap: 12px; padding: 10px 20px; min-height: 58px;
|
|
186
221
|
background: var(--card); border-bottom: 1px solid var(--line);
|
|
@@ -206,7 +241,7 @@ button { font: inherit; color: inherit }
|
|
|
206
241
|
flex: 1; min-height: 0; overflow-y: auto; overflow-anchor: none;
|
|
207
242
|
padding: 16px 20px 28px; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
|
|
208
243
|
}
|
|
209
|
-
.thread-in {
|
|
244
|
+
.thread-in { display: flex; flex-direction: column; gap: 14px }
|
|
210
245
|
.empty { color: var(--faint); text-align: center; padding: 60px 0; font-size: 13px }
|
|
211
246
|
.more-btn {
|
|
212
247
|
align-self: center; background: var(--card); border: 1px solid var(--line); border-radius: 16px;
|
|
@@ -214,15 +249,16 @@ button { font: inherit; color: inherit }
|
|
|
214
249
|
}
|
|
215
250
|
.more-btn:hover { color: var(--accent); border-color: var(--accent) }
|
|
216
251
|
|
|
217
|
-
|
|
218
|
-
.mrow
|
|
219
|
-
|
|
220
|
-
|
|
252
|
+
/* 头像已并进名字那一行, 不再占气泡旁的一列 —— 省下的那一格宽度 (--av) 还给气泡。 */
|
|
253
|
+
.mrow { --av: 24px; display: flex; align-items: flex-start; gap: 10px }
|
|
254
|
+
.mwho .av {
|
|
255
|
+
flex: none; align-self: center; width: var(--av); height: var(--av); border-radius: 50%; border: 1px solid var(--line);
|
|
256
|
+
background: var(--card); font-size: 14px; line-height: 22px; text-align: center; cursor: default; padding: 0;
|
|
221
257
|
}
|
|
222
|
-
.mcol { min-width: 0; max-width: min(78
|
|
258
|
+
.mcol { min-width: 0; max-width: min(78% + var(--av), 760px + var(--av)); display: flex; flex-direction: column; gap: 4px }
|
|
223
259
|
.mrow.mine { flex-direction: row-reverse }
|
|
224
260
|
.mrow.mine .mcol { align-items: flex-end }
|
|
225
|
-
.mwho { font-size: 11.5px; color: var(--mute); display: flex; gap: 6px; align-items:
|
|
261
|
+
.mwho { font-size: 11.5px; color: var(--mute); display: flex; gap: 6px; align-items: center; flex-wrap: wrap }
|
|
226
262
|
.mwho .to { color: var(--faint) }
|
|
227
263
|
.mwho .ch { font-size: 10.5px; border-radius: 4px; padding: 0 4px }
|
|
228
264
|
.mwho .ch.priv { color: var(--priv); background: #9a5b1014 }
|
|
@@ -241,6 +277,7 @@ button { font: inherit; color: inherit }
|
|
|
241
277
|
.mchip.priv { color: var(--priv); background: #9a5b1014 }
|
|
242
278
|
.mchip.pub { color: var(--pub); background: #237a5514 }
|
|
243
279
|
.mchip.graph { color: #6639ba; background: #8250df12 }
|
|
280
|
+
.mchip.sys { color: #0a7d6b; background: #0a7d6b12 }
|
|
244
281
|
|
|
245
282
|
/* 自己发出的那条: 整块就是视角色。TURN_CSS 里写死的白卡 / 灰底 (嵌套气泡、
|
|
246
283
|
代码块、折叠头) 会在蓝底上显成一张张贴纸 —— 这里把它们收回到气泡自己的
|
|
@@ -254,6 +291,9 @@ button { font: inherit; color: inherit }
|
|
|
254
291
|
.mrow.mine .mb .md-body pre code { background: transparent }
|
|
255
292
|
.mrow.mine .mb .bubble details, .mrow.mine .mb .tg-head { border-color: var(--mine-line) }
|
|
256
293
|
.mrow.mine .mb .tool-body { border-left-color: var(--mine-line) }
|
|
294
|
+
/* 工具正文是展开时才取的 (chat.js loadTool) —— 空壳期间说一句在干什么。 */
|
|
295
|
+
.tool-body[data-lazy-turn]:empty::before { content: "加载中…"; color: #8c959f; font-size: 12px }
|
|
296
|
+
.tool-body[data-lazy-turn][data-err]:empty::before { content: "加载失败 · 收起再展开重试"; color: #cf222e }
|
|
257
297
|
.mrow.mine .mb .io-bar { background: var(--mine-soft) }
|
|
258
298
|
|
|
259
299
|
/* 气泡对面那片空白 = 换视角的门。平时不可见, 悬停才露出要去谁那里。 */
|
|
@@ -275,8 +315,8 @@ button { font: inherit; color: inherit }
|
|
|
275
315
|
.flip .fc { flex: none }
|
|
276
316
|
.flip:hover, .flip:focus-visible { background: #2f55c90d; color: var(--accent) }
|
|
277
317
|
.flip[disabled] { cursor: default; background: transparent !important; color: transparent !important }
|
|
278
|
-
.
|
|
279
|
-
.
|
|
318
|
+
.mwho .av.go { cursor: pointer }
|
|
319
|
+
.mwho .av.go:hover { border-color: var(--accent) }
|
|
280
320
|
|
|
281
321
|
.mrow.mark { justify-content: center }
|
|
282
322
|
.mrow.mark > * { flex: 1; max-width: 520px }
|
|
@@ -355,10 +395,15 @@ button { font: inherit; color: inherit }
|
|
|
355
395
|
.chathead { padding: 8px 12px; gap: 8px }
|
|
356
396
|
.chathead .back { display: block }
|
|
357
397
|
.thread { padding: 12px }
|
|
358
|
-
.mcol { max-width: 86% }
|
|
398
|
+
.mcol { max-width: calc(86% + var(--av)) }
|
|
359
399
|
.flip { min-width: 16px; padding: 0 4px; font-size: 0 }
|
|
360
400
|
.turn-group { padding: 12px }
|
|
361
401
|
.thread { padding-bottom: calc(12px + env(safe-area-inset-bottom)) }
|
|
402
|
+
.usage { padding: 8px 12px; gap: 6px 14px }
|
|
403
|
+
.usage .u-kvs, .usage .leg { flex-wrap: wrap }
|
|
404
|
+
.usage .u-io { flex: 1 1 100%; flex-wrap: wrap; gap: 6px 12px }
|
|
405
|
+
.usage .bar { flex: 1 1 100%; width: auto }
|
|
406
|
+
.usage.page { padding-bottom: calc(8px + env(safe-area-inset-bottom)) }
|
|
362
407
|
}
|
|
363
408
|
|
|
364
409
|
/* UA 的 [hidden] 规则和 `.gbar{display:flex}` 这类类选择器同权重, 而作者样式
|