@deepseek-harness-tui/dsh-tui 0.8.5 → 0.8.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.
Files changed (175) hide show
  1. package/bin/dsh-tui.js +0 -0
  2. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
  4. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
  6. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
  7. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
  8. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
  10. package/dsh-ecosystem-spec/registry/README.md +14 -14
  11. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
  12. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
  13. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
  14. package/lib/types/cc/figures.d.ts +7 -0
  15. package/lib/types/cc/figures.d.ts.map +1 -1
  16. package/lib/types/cc/figures.js +23 -0
  17. package/lib/types/cc/markdown.d.ts.map +1 -1
  18. package/lib/types/cc/markdown.js +47 -14
  19. package/lib/types/cc/syntaxTheme.d.ts +12 -0
  20. package/lib/types/cc/syntaxTheme.d.ts.map +1 -0
  21. package/lib/types/cc/syntaxTheme.js +76 -0
  22. package/lib/types/components/EffortChargeGlyph.d.ts +26 -0
  23. package/lib/types/components/EffortChargeGlyph.d.ts.map +1 -0
  24. package/lib/types/components/EffortChargeGlyph.js +70 -0
  25. package/lib/types/components/EffortInputBorder.d.ts +36 -0
  26. package/lib/types/components/EffortInputBorder.d.ts.map +1 -0
  27. package/lib/types/components/EffortInputBorder.js +73 -0
  28. package/lib/types/components/EffortTierBadge.d.ts +26 -0
  29. package/lib/types/components/EffortTierBadge.d.ts.map +1 -0
  30. package/lib/types/components/EffortTierBadge.js +97 -0
  31. package/lib/types/components/LoadedContextPanel.js +1 -1
  32. package/lib/types/components/MessageList.d.ts.map +1 -1
  33. package/lib/types/components/MessageList.js +5 -7
  34. package/lib/types/components/PromptInput.d.ts.map +1 -1
  35. package/lib/types/components/PromptInput.js +8 -3
  36. package/lib/types/components/SplitDiffView.d.ts +1 -4
  37. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  38. package/lib/types/components/SplitDiffView.js +6 -60
  39. package/lib/types/components/StreamingMarkdown.js +1 -1
  40. package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -1
  41. package/lib/types/components/design-system/ThemedBox.js +4 -1
  42. package/lib/types/components/design-system/ThemedText.js +2 -2
  43. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +12 -6
  44. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  45. package/lib/types/components/messages/AssistantThinkingMessage.js +25 -9
  46. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  47. package/lib/types/components/messages/AssistantToolUseMessage.js +35 -18
  48. package/lib/types/components/messages/UserPromptMessage.d.ts +4 -6
  49. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  50. package/lib/types/components/messages/UserPromptMessage.js +5 -9
  51. package/lib/types/dsh-adapter/channel.d.ts +5 -0
  52. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  53. package/lib/types/dsh-adapter/channel.js +43 -0
  54. package/lib/types/screens/Chat.js +1 -2
  55. package/lib/types/theme.d.ts +12 -0
  56. package/lib/types/theme.d.ts.map +1 -1
  57. package/lib/types/theme.js +51 -21
  58. package/lib/types/trajectory/effortIgnition.d.ts +66 -0
  59. package/lib/types/trajectory/effortIgnition.d.ts.map +1 -0
  60. package/lib/types/trajectory/effortIgnition.js +142 -0
  61. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
  62. package/node_modules/@dsh-std/command/LICENSE +21 -21
  63. package/node_modules/@dsh-std/command/README.md +26 -26
  64. package/node_modules/@dsh-std/command/README.zh.md +28 -28
  65. package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
  66. package/node_modules/@dsh-std/command/package.json +22 -22
  67. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  68. package/node_modules/@dsh-std/connection/LICENSE +21 -21
  69. package/node_modules/@dsh-std/connection/README.md +42 -42
  70. package/node_modules/@dsh-std/connection/README.zh.md +42 -42
  71. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  72. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  73. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  74. package/node_modules/@dsh-std/connection/package.json +20 -20
  75. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  76. package/node_modules/@dsh-std/core/LICENSE +21 -21
  77. package/node_modules/@dsh-std/core/README.md +13 -13
  78. package/node_modules/@dsh-std/core/README.zh.md +13 -13
  79. package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  80. package/node_modules/@dsh-std/core/package.json +21 -21
  81. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  82. package/node_modules/@dsh-std/manifest/LICENSE +21 -21
  83. package/node_modules/@dsh-std/manifest/README.md +5 -5
  84. package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  85. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  86. package/node_modules/@dsh-std/manifest/package.json +20 -20
  87. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  88. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
  89. package/node_modules/@dsh-std/messages/LICENSE +21 -21
  90. package/node_modules/@dsh-std/messages/README.md +5 -5
  91. package/node_modules/@dsh-std/messages/README.zh.md +7 -7
  92. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
  93. package/node_modules/@dsh-std/messages/package.json +20 -20
  94. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
  95. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  96. package/node_modules/@dsh-std/presentation/LICENSE +21 -21
  97. package/node_modules/@dsh-std/presentation/README.md +27 -27
  98. package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  99. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  100. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  101. package/node_modules/@dsh-std/presentation/package.json +25 -25
  102. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
  103. package/node_modules/@dsh-std/storage/LICENSE +21 -21
  104. package/node_modules/@dsh-std/storage/README.md +5 -5
  105. package/node_modules/@dsh-std/storage/README.zh.md +7 -7
  106. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
  107. package/node_modules/@dsh-std/storage/package.json +20 -20
  108. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
  109. package/package.json +1 -1
  110. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  111. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
  112. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
  113. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
  114. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  115. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  116. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  117. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
  118. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  119. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
  120. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
  121. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
  122. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  123. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
  124. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  125. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
  126. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
  127. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  128. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  129. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
  130. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  131. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  132. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
  133. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
  134. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  135. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  136. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  137. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
  138. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  139. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
  140. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
  141. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
  142. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  143. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
  144. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  145. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
  146. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
  147. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
  148. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  149. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
  150. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  151. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
  152. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
  153. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
  154. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  155. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
  156. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  157. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
  158. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
  159. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
  160. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  161. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  162. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  163. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
  164. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  165. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
  166. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
  167. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
  168. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  169. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
  170. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  171. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
  172. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
  173. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
  174. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  175. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
@@ -0,0 +1,36 @@
1
+ /**
2
+ * EffortInputBorder — 输入框层上的三幕点焰叠加(对齐 Codex 的完整
3
+ * 语义:光扫过、档位字样浮现、整体渐隐)。
4
+ *
5
+ * 输入框只有顶/底两条横边框(round、无左右)——本组件自绘这两行,
6
+ * **同步**承载动画;档位字样由输入行尾的 EffortTierBadge 短暂显示
7
+ * (见 PromptInput),动画全程行数恒定。切到最高思考强度档时:
8
+ *
9
+ * 1. 扫光 [0, 1s)——一段高亮彩色光带沿顶/底边框同步自左向右扫过
10
+ * (wave 波形逐列变色),期间输入框完全正常可用;
11
+ * 2. 档位字样 [600ms, ~1.1s)——光带行至中段时,输入行居中浮现
12
+ * 档名大写(由暗渐亮加粗、间距聚拢,见 EffortTierBadge);
13
+ * 3. 渐隐 [1.5s, 2s)——字样连同光色一起向主题色淡出,末帧归零:
14
+ * 静止时顶/底边框就是原主题色,内容区无任何附加物。
15
+ *
16
+ * glyph 变化仅限字样行的出现/让位(一次性);其余帧间变化全部是既
17
+ * 有 `─` 的前景色。触发判定在渲染期做(props-变化-调整模式);从
18
+ * 「已有档位」切到档位表末位最高档才触发,冷启动恢复偏好/单档表/
19
+ * 无档位表/无共享时钟均不触发。时钟复用 Ink core 共享时钟,仅动画
20
+ * 窗口订阅(keepAlive),播完回到零开销静止边框。
21
+ */
22
+ import React from 'react';
23
+ import type { Color } from '../ink/styles.js';
24
+ import type { Theme } from '../theme.js';
25
+ export declare function EffortInputBorder({ effort, levels, columns, onLight, idleColor, children, }: {
26
+ /** 当前思考强度档 id;`undefined` 表示路线未声明。 */
27
+ effort: string | undefined;
28
+ /** 当前路线的档位表(低→高,末位为最高档);未知时传 `undefined`。 */
29
+ levels: readonly string[] | undefined;
30
+ columns: number;
31
+ onLight: boolean;
32
+ /** 静止边框色(主题 token 名,如 'promptBorder' / 'planMode')。 */
33
+ idleColor: keyof Theme | Color;
34
+ children: React.ReactNode;
35
+ }): React.ReactNode;
36
+ //# sourceMappingURL=EffortInputBorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EffortInputBorder.d.ts","sourceRoot":"","sources":["../../../src/components/EffortInputBorder.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAA8D,MAAM,OAAO,CAAA;AAGlF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AA8BxC,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GACT,EAAE;IACD,sCAAsC;IACtC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,GAAG,KAAK,CAAC,SAAS,CA0DlB"}
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * EffortInputBorder — 输入框层上的三幕点焰叠加(对齐 Codex 的完整
4
+ * 语义:光扫过、档位字样浮现、整体渐隐)。
5
+ *
6
+ * 输入框只有顶/底两条横边框(round、无左右)——本组件自绘这两行,
7
+ * **同步**承载动画;档位字样由输入行尾的 EffortTierBadge 短暂显示
8
+ * (见 PromptInput),动画全程行数恒定。切到最高思考强度档时:
9
+ *
10
+ * 1. 扫光 [0, 1s)——一段高亮彩色光带沿顶/底边框同步自左向右扫过
11
+ * (wave 波形逐列变色),期间输入框完全正常可用;
12
+ * 2. 档位字样 [600ms, ~1.1s)——光带行至中段时,输入行居中浮现
13
+ * 档名大写(由暗渐亮加粗、间距聚拢,见 EffortTierBadge);
14
+ * 3. 渐隐 [1.5s, 2s)——字样连同光色一起向主题色淡出,末帧归零:
15
+ * 静止时顶/底边框就是原主题色,内容区无任何附加物。
16
+ *
17
+ * glyph 变化仅限字样行的出现/让位(一次性);其余帧间变化全部是既
18
+ * 有 `─` 的前景色。触发判定在渲染期做(props-变化-调整模式);从
19
+ * 「已有档位」切到档位表末位最高档才触发,冷启动恢复偏好/单档表/
20
+ * 无档位表/无共享时钟均不触发。时钟复用 Ink core 共享时钟,仅动画
21
+ * 窗口订阅(keepAlive),播完回到零开销静止边框。
22
+ */
23
+ import { useContext, useEffect, useReducer, useState } from 'react';
24
+ import { Box, Text } from '../ui.js';
25
+ import { ClockContext } from '../ink/components/ClockContext.js';
26
+ import { IGNITION_TIMELINE, ignitionLineColors } from '../trajectory/effortIgnition.js';
27
+ /** 边框行(顶/底共用同一色段序列——同步变色)。 */
28
+ function BorderRow({ left, right, runs, idleColor, }) {
29
+ return (_jsxs(Text, { children: [_jsx(Text, { color: idleColor, children: left }), runs.map((run, i) => (_jsx(Text, { color: run.color, children: run.glyph }, i))), _jsx(Text, { color: idleColor, children: right })] }));
30
+ }
31
+ export function EffortInputBorder({ effort, levels, columns, onLight, idleColor, children, }) {
32
+ const clock = useContext(ClockContext);
33
+ const [overlay, setOverlay] = useState(null);
34
+ const [prevEffort, setPrevEffort] = useState(effort);
35
+ const [, forceRender] = useReducer((tick) => tick + 1, 0);
36
+ // 渲染期触发:effort 变化的首帧就以新状态渲染(effect 会晚一帧)。
37
+ if (effort !== prevEffort) {
38
+ setPrevEffort(effort);
39
+ if (clock !== null &&
40
+ effort !== undefined &&
41
+ levels !== undefined &&
42
+ levels.length > 1 &&
43
+ effort === levels[levels.length - 1]) {
44
+ setOverlay({ label: effort.toUpperCase(), startedAtMs: clock.now() });
45
+ }
46
+ }
47
+ // 仅动画窗口订阅共享时钟;静止边框零定时器零重渲染。
48
+ const elapsedMs = overlay === null ? Infinity : Math.max(0, (clock?.now() ?? Date.now()) - overlay.startedAtMs);
49
+ useEffect(() => {
50
+ if (overlay === null || clock === null)
51
+ return;
52
+ return clock.subscribe(() => forceRender(), /* keepAlive */ true);
53
+ }, [overlay, clock]);
54
+ useEffect(() => {
55
+ if (overlay !== null && elapsedMs >= IGNITION_TIMELINE.fadeEndMs)
56
+ setOverlay(null);
57
+ }, [overlay, elapsedMs]);
58
+ const midWidth = Math.max(0, columns - 2);
59
+ const sweepColors = overlay !== null && elapsedMs < IGNITION_TIMELINE.sweepMs && midWidth > 0
60
+ ? ignitionLineColors({ elapsedMs, width: midWidth, onLight })
61
+ : [];
62
+ // 顶/底共用的色段序列(同步):扫光列取波形色,其余列回主题色。
63
+ const runs = [];
64
+ for (let index = 0; index < midWidth; index++) {
65
+ const color = sweepColors[index] ?? idleColor;
66
+ const last = runs[runs.length - 1];
67
+ if (last !== undefined && last.color === color)
68
+ last.glyph += '─';
69
+ else
70
+ runs.push({ glyph: '─', color });
71
+ }
72
+ return (_jsxs(Box, { flexDirection: "column", alignItems: "flex-start", justifyContent: "flex-start", width: "100%", flexShrink: 0, children: [_jsx(BorderRow, { left: "\u256D", right: "\u256E", runs: runs, idleColor: idleColor }), children, _jsx(BorderRow, { left: "\u2570", right: "\u256F", runs: runs, idleColor: idleColor })] }));
73
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * EffortTierBadge — 输入行尾的档位字样徽标:三幕点焰的第二幕载体
3
+ * (与 EffortInputBorder 的双框扫光同一时间轴、同一触发),切到最高
4
+ * 思考强度档时光带行至中段,输入行居中浮现档名(当前档名大写,字母间距从
5
+ * 10 个空格减速聚拢到 1 个——连续位置逐字母取整保证帧帧有移动,
6
+ * 明亮蓝加粗,由暗渐亮),随后随图层整体渐隐让位——行数恒定,静
7
+ * 止时完全不渲染;输入行有文字时不显示(绝不遮挡内容)。
8
+ *
9
+ * 触发判定在渲染期做(props-变化-调整模式,与边框/充能组件同模
10
+ * 式);冷启动恢复偏好/单档表/无档位表/无共享时钟均不触发。时钟
11
+ * 复用 Ink core 共享时钟,仅动画窗口订阅(keepAlive),播完归零。
12
+ */
13
+ import React from 'react';
14
+ export declare function EffortTierBadge({ effort, levels, onLight, columns, leadingColumns, }: {
15
+ /** 当前思考强度档 id;`undefined` 表示路线未声明。 */
16
+ effort: string | undefined;
17
+ /** 当前路线的档位表(低→高,末位为最高档);未知时传 `undefined`。 */
18
+ levels: readonly string[] | undefined;
19
+ onLight: boolean;
20
+ /** 终端列数——居中锚点按终端几何中心计算(纯文本流,不引入嵌套 Box)。 */
21
+ columns: number;
22
+ /** badge 文本流之前该行已被占据的列数(❯ 与块光标等)——居中换算成
23
+ * badge 流内列时要扣掉,否则整体偏右一个前缀宽。 */
24
+ leadingColumns: number;
25
+ }): React.ReactNode;
26
+ //# sourceMappingURL=EffortTierBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EffortTierBadge.d.ts","sourceRoot":"","sources":["../../../src/components/EffortTierBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAsD,MAAM,OAAO,CAAA;AAc1E,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,cAAc,GACf,EAAE;IACD,sCAAsC;IACtC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IACf;qCACiC;IACjC,cAAc,EAAE,MAAM,CAAA;CACvB,GAAG,KAAK,CAAC,SAAS,CAkFlB"}
@@ -0,0 +1,97 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * EffortTierBadge — 输入行尾的档位字样徽标:三幕点焰的第二幕载体
4
+ * (与 EffortInputBorder 的双框扫光同一时间轴、同一触发),切到最高
5
+ * 思考强度档时光带行至中段,输入行居中浮现档名(当前档名大写,字母间距从
6
+ * 10 个空格减速聚拢到 1 个——连续位置逐字母取整保证帧帧有移动,
7
+ * 明亮蓝加粗,由暗渐亮),随后随图层整体渐隐让位——行数恒定,静
8
+ * 止时完全不渲染;输入行有文字时不显示(绝不遮挡内容)。
9
+ *
10
+ * 触发判定在渲染期做(props-变化-调整模式,与边框/充能组件同模
11
+ * 式);冷启动恢复偏好/单档表/无档位表/无共享时钟均不触发。时钟
12
+ * 复用 Ink core 共享时钟,仅动画窗口订阅(keepAlive),播完归零。
13
+ */
14
+ import { useContext, useEffect, useReducer, useState } from 'react';
15
+ import { Text } from '../ui.js';
16
+ import { ClockContext } from '../ink/components/ClockContext.js';
17
+ import { rgbString } from '../trajectory/motion.js';
18
+ import { IGNITION_TIMELINE, ignitionHues } from '../trajectory/effortIgnition.js';
19
+ /** 字母间距聚拢:从 10 个空格减速收敛到 1 个(ease-out,快收慢停)。 */
20
+ const GAP_START = 10;
21
+ const GAP_END = 1;
22
+ const CONVERGE_MS = 500;
23
+ export function EffortTierBadge({ effort, levels, onLight, columns, leadingColumns, }) {
24
+ const clock = useContext(ClockContext);
25
+ const [overlay, setOverlay] = useState(null);
26
+ const [prevEffort, setPrevEffort] = useState(effort);
27
+ const [, forceRender] = useReducer((tick) => tick + 1, 0);
28
+ // 渲染期触发(与边框/充能同模式):effort 变化的首帧就以新状态渲染。
29
+ if (effort !== prevEffort) {
30
+ setPrevEffort(effort);
31
+ if (clock !== null &&
32
+ effort !== undefined &&
33
+ levels !== undefined &&
34
+ levels.length > 1 &&
35
+ effort === levels[levels.length - 1]) {
36
+ setOverlay({ label: effort.toUpperCase(), startedAtMs: clock.now() });
37
+ }
38
+ }
39
+ const elapsedMs = overlay === null ? Infinity : Math.max(0, (clock?.now() ?? Date.now()) - overlay.startedAtMs);
40
+ useEffect(() => {
41
+ if (overlay === null || clock === null)
42
+ return;
43
+ return clock.subscribe(() => forceRender(), /* keepAlive */ true);
44
+ }, [overlay, clock]);
45
+ useEffect(() => {
46
+ if (overlay !== null && elapsedMs >= IGNITION_TIMELINE.fadeEndMs)
47
+ setOverlay(null);
48
+ }, [overlay, elapsedMs]);
49
+ if (overlay === null || elapsedMs < IGNITION_TIMELINE.labelStartMs)
50
+ return null;
51
+ const brighten = Math.min(1, (elapsedMs - IGNITION_TIMELINE.labelStartMs) / IGNITION_TIMELINE.labelBrightenMs);
52
+ const fade = elapsedMs < IGNITION_TIMELINE.fadeStartMs
53
+ ? 1
54
+ : Math.max(0, 1 - (elapsedMs - IGNITION_TIMELINE.fadeStartMs) / (IGNITION_TIMELINE.fadeEndMs - IGNITION_TIMELINE.fadeStartMs));
55
+ const alpha = brighten * fade;
56
+ if (alpha <= 0)
57
+ return null;
58
+ const band = onLight ? { r: 240, g: 240, b: 242 } : { r: 27, g: 30, b: 40 };
59
+ // 明亮蓝:accent 混白 35% 提亮(用户拍板的高亮观感)。
60
+ const hue = ignitionHues(onLight)[0];
61
+ const whiten = (x) => Math.round(x + (255 - x) * 0.35);
62
+ const bright = { r: whiten(hue.r), g: whiten(hue.g), b: whiten(hue.b) };
63
+ const mix = (x, y) => Math.round(x + (y - x) * alpha);
64
+ const color = rgbString({ r: mix(band.r, bright.r), g: mix(band.g, bright.g), b: mix(band.b, bright.b) });
65
+ // 字母间距聚拢(Codex 的 converge 语义):间距是连续浮点,字母位置
66
+ // 以**行中心为锚**对称收缩——pos_i = center + (i-(n-1)/2)·(1+gap),
67
+ // 左右字母各向中心移动一半(奇数档名的居中字母原位不动),两侧速
68
+ // 度天然均衡;每字母独立按连续位置取整落列,不同字母在不同帧跨
69
+ // 格,每帧至少一个在动(把间距整体取整会让 ease-out 慢末段上百毫
70
+ // 秒才跨一格,看起来就是卡顿)。曲线混入 15% 线性做末段保底速度。
71
+ const progress = Math.min(1, Math.max(0, (elapsedMs - IGNITION_TIMELINE.labelStartMs) / CONVERGE_MS));
72
+ // 跳变间隔均匀化:离散格子上「减速」若靠曲线导数趋零实现,末段会
73
+ // 出现几十帧不动一格的长停顿再突跳(卡感来源)。改为 90% 线性 +
74
+ // 10% easeOutQuad 的轻缓收尾——跳变间隔全程近似恒定(约 55ms/格),
75
+ // 仅末端轻微放慢,终端上的观感是均匀顺滑的聚拢。
76
+ const eased = 1 - progress;
77
+ const easedWithFloor = 0.9 * eased + 0.1 * (1 - progress * progress);
78
+ const gapF = GAP_END + (GAP_START - GAP_END) * easedWithFloor;
79
+ const letterCount = overlay.label.length;
80
+ // 锚点是**终端几何中心**(不是 ❯/光标之后可用区的中心——那会整体
81
+ // 偏右约 1.5 格;可用区起点在左,其"中点"不含左部占位)。左右字母
82
+ // 严格镜像——Math.round 对 .5 恒向上,正负方向舍入不对称会让跨格
83
+ // 时刻错开;左字母的落列由右字母的舍入结果镜像得出(2C − col),
84
+ // M/X 每次同帧反向同跳,全程对称于终端中心。
85
+ const C = Math.round((columns - 1) / 2) - leadingColumns;
86
+ let spaced = '';
87
+ let column = 0;
88
+ for (let i = 0; i < letterCount; i++) {
89
+ const off = (i - (letterCount - 1) / 2) * (1 + gapF);
90
+ const at = off >= 0
91
+ ? Math.round(C + off)
92
+ : 2 * C - Math.round(C - off);
93
+ spaced += ' '.repeat(Math.max(0, at - column)) + overlay.label[i];
94
+ column = at + 1;
95
+ }
96
+ return (_jsx(Text, { bold: true, color: color, children: spaced }));
97
+ }
@@ -26,5 +26,5 @@ export function LoadedContextPanel({ context, open, onToggle, }) {
26
26
  const summary = summarizeLoadedContext(context);
27
27
  if (summary === '')
28
28
  return null;
29
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Box, { paddingX: 1, backgroundColor: open ? 'userMessageBackground' : undefined, children: _jsxs(Text, { bold: open, wrap: "truncate", children: [open ? '▼' : '▶', " ", _jsxs(Text, { dimColor: true, children: ["\uFF08Ctrl+P", open ? t('context-panel-collapse') : t('context-panel-expand'), "\uFF09"] }), " ", t('context-loaded'), " \u00B7 ", summary] }) }), open && (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [context.sections.length > 0 && (_jsx(Group, { title: t('context-panel-sections', { n: context.sections.length }), children: context.sections.map(section => (_jsx(Entry, { entry: section }, section.name))) })), context.files.length > 0 && (_jsx(Group, { title: t('context-panel-files', { n: context.files.length }), children: context.files.map(file => (_jsx(Text, { dimColor: true, children: file.displayPath }, file.displayPath))) })), context.contexts.length > 0 && (_jsx(Group, { title: t('context-panel-runtime', { n: context.contexts.length }), children: context.contexts.map(entry => (_jsx(Entry, { entry: entry }, entry.name))) })), context.skills.length > 0 && (_jsx(Group, { title: t('context-panel-skills', { n: context.skills.length }), children: context.skills.map(skill => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: skill.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: skill.description })] }, skill.name))) })), context.tools.length > 0 && (_jsx(Group, { title: t('context-panel-tools', { n: context.tools.length }), children: context.tools.map(tool => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: tool.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(tool.description, 160) })] }, tool.name))) })), _jsx(Text, { dimColor: true, children: "\u00B7 /context" })] }))] }));
29
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Box, { paddingX: 1, backgroundColor: open ? 'userMessageBackgroundHover' : undefined, children: _jsxs(Text, { bold: open, wrap: "truncate", children: [open ? '▼' : '▶', " ", _jsxs(Text, { dimColor: true, children: ["\uFF08Ctrl+P", open ? t('context-panel-collapse') : t('context-panel-expand'), "\uFF09"] }), " ", t('context-loaded'), " \u00B7 ", summary] }) }), open && (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [context.sections.length > 0 && (_jsx(Group, { title: t('context-panel-sections', { n: context.sections.length }), children: context.sections.map(section => (_jsx(Entry, { entry: section }, section.name))) })), context.files.length > 0 && (_jsx(Group, { title: t('context-panel-files', { n: context.files.length }), children: context.files.map(file => (_jsx(Text, { dimColor: true, children: file.displayPath }, file.displayPath))) })), context.contexts.length > 0 && (_jsx(Group, { title: t('context-panel-runtime', { n: context.contexts.length }), children: context.contexts.map(entry => (_jsx(Entry, { entry: entry }, entry.name))) })), context.skills.length > 0 && (_jsx(Group, { title: t('context-panel-skills', { n: context.skills.length }), children: context.skills.map(skill => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: skill.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: skill.description })] }, skill.name))) })), context.tools.length > 0 && (_jsx(Group, { title: t('context-panel-tools', { n: context.tools.length }), children: context.tools.map(tool => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: tool.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(tool.description, 160) })] }, tool.name))) })), _jsx(Text, { dimColor: true, children: "\u00B7 /context" })] }))] }));
30
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAa/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AA2B3D,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,YAAwB,EACxB,cAAuB,EACvB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,mEAAmE;IACnE,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC,qEAAqE;IACrE,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBA+VA;AAsRD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAa/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AA2B3D,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,YAAwB,EACxB,cAAuB,EACvB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,mEAAmE;IACnE,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC,qEAAqE;IACrE,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBA8VA;AAsRD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
@@ -17,7 +17,7 @@ import { truncateToWidth } from '../ink/truncateToWidth.js';
17
17
  /**
18
18
  * Transcript rows rendered in the Claude Code visual language: user prompts
19
19
  * on a grey bubble with a `❯` pointer, assistant text with a `●` bullet and
20
- * markdown, thinking folded to `∴ Thinking (ctrl+o to expand)`, tool calls as
20
+ * markdown, thinking folded to `⚓ Thinking (ctrl+o to expand)`, tool calls as
21
21
  * status-dot cards. `expanded` (Ctrl+O) shows full reasoning + full tool
22
22
  * args/results; `expandedRows` (message-selection mode, Enter) expands single
23
23
  * rows; `selectedId` highlights the selected row.
@@ -54,14 +54,12 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
54
54
  prev = row.kind;
55
55
  }
56
56
  }
57
- // CC's expanded rows keep a persistent hover-grey background (VirtualItem:
58
- // `expanded ? userMessageBackgroundHover : undefined`).
57
+ // Selection keeps its highlight; expanded rows render with no fill (the
58
+ // diff line tints inside cards are the only backgrounds in the transcript).
59
59
  const rowBackground = (rowId) => {
60
60
  const isSelected = selectedId === rowId;
61
61
  if (isSelected)
62
62
  return 'messageActionsBackground';
63
- if (expandedRows.has(rowId))
64
- return 'userMessageBackgroundHover';
65
63
  return undefined;
66
64
  };
67
65
  // --- layout virtualization ---------------------------------------------
@@ -346,11 +344,11 @@ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, duration
346
344
  }, [onToggleRow, rowId]);
347
345
  switch (kind) {
348
346
  case 'user':
349
- return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(UserPromptMessage, { text: text, addMargin: addMargin, isSelected: isSelected, isExpanded: isExpanded, onClick: onClick }) }));
347
+ return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(UserPromptMessage, { text: text, addMargin: addMargin, isSelected: isSelected, onClick: onClick }) }));
350
348
  case 'assistant':
351
349
  return streaming ? (_jsxs(Box, { alignItems: "flex-start", flexDirection: "row", marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: background, children: [_jsx(Box, { minWidth: 2, children: _jsx(Text, { color: "text", children: "\u25CF" }) }), _jsx(Box, { flexDirection: "column", children: _jsx(StreamingMarkdown, { children: stripNarration(text) }) })] })) : (_jsxs(Box, { width: "100%", flexDirection: "column", backgroundColor: background, ref: ref, children: [expanded && (_jsx(Box, { flexDirection: "row", justifyContent: "flex-end", gap: 1, marginTop: 1, children: _jsx(MessageMetadata, { timestamp: time, model: model }) })), _jsx(AssistantTextMessage, { text: stripNarration(text), addMargin: addMargin, isSelected: isSelected, isExpanded: isExpanded, onClick: onClick })] }));
352
350
  case 'reasoning':
353
- return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin, preview: streaming &&
351
+ return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin, streaming: streaming, preview: streaming &&
354
352
  thinkingFold === 'preview' &&
355
353
  !expanded &&
356
354
  !isExpanded,
@@ -1 +1 @@
1
- {"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,qBA25BlB"}
1
+ {"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,qBA46BlB"}
@@ -1,9 +1,13 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { readFile, unlink } from 'node:fs/promises';
4
4
  import { basename } from 'node:path';
5
5
  import { t } from '../i18n.js';
6
- import { Box, Text, useInput, useTerminalSize } from '../ui.js';
6
+ import { Box, Text, useInput, useTerminalSize, useTheme } from '../ui.js';
7
+ import { EffortChargeGlyph } from './EffortChargeGlyph.js';
8
+ import { EffortInputBorder } from './EffortInputBorder.js';
9
+ import { EffortTierBadge } from './EffortTierBadge.js';
10
+ import { isLightThemeActive } from '../theme.js';
7
11
  import { useDeclaredCursor } from '../ink/hooks/use-declared-cursor.js';
8
12
  import { stringWidth } from '../ink/stringWidth.js';
9
13
  import { formatClipboardInsert, readClipboard } from '../utils/clipboard.js';
@@ -89,6 +93,7 @@ const MAX_VISIBLE_LINES = 5;
89
93
  * aborts the turn and sends the current input immediately.
90
94
  */
91
95
  export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, selectionActive, fillText, onFillConsumed, onRewindRequest, controllerRef, }) {
96
+ const [themeName] = useTheme();
92
97
  const [value, setValue] = React.useState('');
93
98
  const [cursor, setCursor] = React.useState(0);
94
99
  const valueRef = React.useRef(value);
@@ -882,7 +887,7 @@ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, sel
882
887
  .filter(item => item.placement === 'steer')
883
888
  .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), channel.pending.some(item => item.placement === 'followup') && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["\u23F3 ", t('input-pending-queue-label')] }), channel.pending
884
889
  .filter(item => item.placement === 'followup')
885
- .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), _jsxs(Text, { dimColor: true, children: ["Alt+\u2191 ", t('input-pending-actions-hint')] })] })), fileOverlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(FileSuggestions, { files: fileMatches, selectedIndex: fileSelected, columns: columns }) })), overlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(CommandSuggestions, { commands: suggestions, selectedIndex: selectedCommand, columns: columns }) }))] })), lastNotification && (_jsx(Box, { position: "absolute", marginTop: -1, height: 1, width: "100%", paddingLeft: 2, paddingRight: 1, flexDirection: "column", justifyContent: "flex-end", overflow: "hidden", children: _jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { color: lastNotification.color, dimColor: !lastNotification.color, wrap: "truncate", children: lastNotification.text }) }) })), _jsx(Box, { flexDirection: "column", alignItems: "flex-start", justifyContent: "flex-start", borderColor: channel.mode.plan === true ? 'planMode' : 'promptBorder', borderStyle: "round", borderLeft: false, borderRight: false, borderBottom: true, width: "100%", children: _jsxs(Box, { flexDirection: "row", alignItems: "flex-start", width: "100%", children: [_jsx(Text, { dimColor: channel.working, children: "\u276F " }), _jsx(Box, { ref: valueBoxRef, flexGrow: 1, flexShrink: 1, children: value.length === 0 ? (_jsx(Text, { inverse: true, children: " " })) : (_jsx(Box, { flexDirection: "column", children: rendered })) })] }) })] }));
890
+ .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), _jsxs(Text, { dimColor: true, children: ["Alt+\u2191 ", t('input-pending-actions-hint')] })] })), fileOverlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(FileSuggestions, { files: fileMatches, selectedIndex: fileSelected, columns: columns }) })), overlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(CommandSuggestions, { commands: suggestions, selectedIndex: selectedCommand, columns: columns }) }))] })), lastNotification && (_jsx(Box, { position: "absolute", marginTop: -1, height: 1, width: "100%", paddingLeft: 2, paddingRight: 1, flexDirection: "column", justifyContent: "flex-end", overflow: "hidden", children: _jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { color: lastNotification.color, dimColor: !lastNotification.color, wrap: "truncate", children: lastNotification.text }) }) })), _jsx(EffortInputBorder, { effort: channel.reasoningEffort, levels: channel.effortLevels, columns: columns, onLight: isLightThemeActive(themeName), idleColor: channel.mode.plan === true ? 'planMode' : 'promptBorder', children: _jsxs(Box, { flexDirection: "row", alignItems: "flex-start", width: "100%", children: [_jsx(EffortChargeGlyph, { effort: channel.reasoningEffort, levels: channel.effortLevels, working: channel.working }), _jsx(Box, { ref: valueBoxRef, flexGrow: 1, flexShrink: 1, children: value.length === 0 ? (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: " " }), _jsx(EffortTierBadge, { effort: channel.reasoningEffort, levels: channel.effortLevels, onLight: isLightThemeActive(themeName), columns: columns, leadingColumns: 3 })] })) : (_jsx(Box, { flexDirection: "column", children: rendered })) })] }) })] }));
886
891
  }
887
892
  /**
888
893
  * Hard-wrap text into visual rows of at most `width` columns (CJK-aware via
@@ -1,11 +1,8 @@
1
1
  import React from 'react';
2
2
  import type { ToolFileDiff } from '../dsh-adapter/channel.js';
3
3
  import { type CliHighlight } from '../cc/cliHighlight.js';
4
+ export { chalkFromToken } from '../cc/syntaxTheme.js';
4
5
  import type { ToolBackground } from '../tuiDisplayPrefs.js';
5
- /** chalk style for one raw theme value. Accepts every form the theme
6
- * loader documents: #rgb, #rrggbb, #rrggbbaa (alpha stripped), rgb() with
7
- * or without spaces, ansi256(n), ansi:name (issue #250, P2-5). */
8
- export declare function chalkFromToken(token: string): (text: string) => string;
9
6
  /** Parse a cli-highlight ANSI string into colored runs, preserving open
10
7
  * spans across embedded newlines (multi-line strings/comments). Handles
11
8
  * truecolor 38;2, 256-color 38;5 (tmux / FORCE_COLOR=2, issue #250 P1-1),
@@ -1 +1 @@
1
- {"version":3,"file":"SplitDiffView.d.ts","sourceRoot":"","sources":["../../../src/components/SplitDiffView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAGjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAsF3D;;mEAEmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAmBtE;AAUD;;;oCAGoC;AACpC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAuB9E;AAuBD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,EAAE,EAAE,YAAY,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,EAC7D,QAAQ,EAAE,MAAM,GACf,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAAE,GAAG,SAAS,CAe3D;AAsOD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,cAAuB,GACxB,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CACzC,GAAG,KAAK,CAAC,SAAS,CAiGlB"}
1
+ {"version":3,"file":"SplitDiffView.d.ts","sourceRoot":"","sources":["../../../src/components/SplitDiffView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIjF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAgE3D;;;oCAGoC;AACpC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAuB9E;AAuBD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,EAAE,EAAE,YAAY,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,EAC7D,QAAQ,EAAE,MAAM,GACf,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAAE,GAAG,SAAS,CAe3D;AAsOD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,cAAuB,GACxB,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CACzC,GAAG,KAAK,CAAC,SAAS,CAiGlB"}
@@ -2,73 +2,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Box, Text } from '../ui.js';
4
4
  import * as JsDiff from 'diff';
5
- import chalk from 'chalk';
6
5
  import { extname } from 'node:path';
7
6
  import { getCliHighlightPromise } from '../cc/cliHighlight.js';
7
+ import { SYNTAX_CLASS_TO_TOKEN, chalkFromToken } from '../cc/syntaxTheme.js';
8
+ // Backward-compatible re-export: repro scripts import chalkFromToken from
9
+ // this module's old home.
10
+ export { chalkFromToken } from '../cc/syntaxTheme.js';
8
11
  import { getTheme } from '../theme.js';
9
12
  import { useTheme } from './design-system/ThemeProvider.js';
10
13
  /** Replace tabs so width math and alignment hold (pi convention). */
11
14
  const expandTabs = (text) => text.replaceAll('\t', ' ');
12
15
  // --- syntax highlighting ----------------------------------------------------
13
- /** highlight.js token classes → theme syntax tokens. `default` catches
14
- * every unmapped class so cli-highlight's own yellow never leaks through
15
- * (issue #250, P2-6). */
16
- const SYNTAX_CLASS_TO_TOKEN = {
17
- keyword: 'syntaxKeyword',
18
- built_in: 'syntaxKeyword',
19
- literal: 'syntaxKeyword',
20
- string: 'syntaxString',
21
- subst: 'syntaxString',
22
- quote: 'syntaxString',
23
- comment: 'syntaxComment',
24
- number: 'syntaxNumber',
25
- title: 'syntaxFunction',
26
- 'title.function_': 'syntaxFunction',
27
- function: 'syntaxFunction',
28
- 'title.class_': 'syntaxType',
29
- type: 'syntaxType',
30
- class: 'syntaxType',
31
- tag: 'syntaxType',
32
- name: 'syntaxType',
33
- attr: 'syntaxVariable',
34
- attribute: 'syntaxVariable',
35
- variable: 'syntaxVariable',
36
- 'template-variable': 'syntaxVariable',
37
- params: 'syntaxVariable',
38
- operator: 'syntaxOperator',
39
- punctuation: 'syntaxPunctuation',
40
- meta: 'syntaxPunctuation',
41
- symbol: 'syntaxConstant',
42
- regexp: 'syntaxConstant',
43
- default: 'syntaxVariable',
44
- };
45
- /** chalk style for one raw theme value. Accepts every form the theme
46
- * loader documents: #rgb, #rrggbb, #rrggbbaa (alpha stripped), rgb() with
47
- * or without spaces, ansi256(n), ansi:name (issue #250, P2-5). */
48
- export function chalkFromToken(token) {
49
- let match = /^#([0-9a-fA-F]{3})$/.exec(token);
50
- if (match !== null) {
51
- const [r, g, b] = match[1].split('').map(c => parseInt(c + c, 16));
52
- return chalk.rgb(r, g, b);
53
- }
54
- match = /^#([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(token);
55
- if (match !== null)
56
- return chalk.hex(`#${match[1]}`);
57
- match = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/.exec(token);
58
- if (match !== null)
59
- return chalk.rgb(Number(match[1]), Number(match[2]), Number(match[3]));
60
- match = /^ansi256\((\d+)\)$/.exec(token);
61
- if (match !== null)
62
- return chalk.ansi256(Number(match[1]));
63
- match = /^ansi:(\w+)$/.exec(token);
64
- if (match !== null) {
65
- const name = match[1] === 'blackBright' ? 'gray' : match[1];
66
- const style = chalk[name];
67
- if (style !== undefined)
68
- return style;
69
- }
70
- return (text) => text;
71
- }
16
+ // The hljs-class → theme-token map and chalkFromToken live in
17
+ // ../cc/syntaxTheme.ts (shared with the markdown code-block renderer).
72
18
  /** ANSI 16-color SGR codes → rgb() strings (the dark-ansi palette path). */
73
19
  const ANSI16 = {
74
20
  30: 'rgb(0,0,0)', 31: 'rgb(128,0,0)', 32: 'rgb(0,128,0)', 33: 'rgb(128,128,0)',
@@ -85,5 +85,5 @@ export function StreamingMarkdown({ children, dimColor = false, }) {
85
85
  // an overlapping empty/duplicate boundary.
86
86
  const hasDistinctSuffix = unstableSuffix !== '' &&
87
87
  (stablePrefix === '' || !unstableSuffix.startsWith(stablePrefix));
88
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [stablePrefix && _jsx(Markdown, { dimColor: true, children: stablePrefix }), hasDistinctSuffix && _jsx(Markdown, { dimColor: true, cacheTokens: false, children: unstableSuffix })] }));
88
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [stablePrefix && _jsx(Markdown, { dimColor: dimColor, children: stablePrefix }), hasDistinctSuffix && _jsx(Markdown, { dimColor: dimColor, cacheTokens: false, children: unstableSuffix })] }));
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ThemedBox.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemedBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAY,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAIrD,KAAK,gBAAgB,GAAG;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC7C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAChD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC9C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;CAC/C,CAAA;AAGD,KAAK,uBAAuB,GAAG,IAAI,CACjC,MAAM,EACJ,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,CACpB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,uBAAuB,GACzC,gBAAgB,GAAG;IACjB,GAAG,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACrC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC3C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC1C,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACjD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B,CAAA;AAmBH;;;GAGG;AACH,iBAAS,SAAS,CAAC,EACjB,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,GAAG,IAAI,EACR,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAc5C;AACD,eAAe,SAAS,CAAA"}
1
+ {"version":3,"file":"ThemedBox.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemedBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAY,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAIrD,KAAK,gBAAgB,GAAG;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC7C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAChD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC9C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;CAC/C,CAAA;AAGD,KAAK,uBAAuB,GAAG,IAAI,CACjC,MAAM,EACJ,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,CACpB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,uBAAuB,GACzC,gBAAgB,GAAG;IACjB,GAAG,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACrC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC5C,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC3C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC1C,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACjD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B,CAAA;AAsBH;;;GAGG;AACH,iBAAS,SAAS,CAAC,EACjB,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,GAAG,IAAI,EACR,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAc5C;AACD,eAAe,SAAS,CAAA"}
@@ -12,7 +12,10 @@ function resolveColor(color, theme) {
12
12
  color.startsWith('ansi:')) {
13
13
  return color;
14
14
  }
15
- return theme[color];
15
+ // Theme keys may be '' ("no color" in that theme) - collapse to undefined
16
+ // so empty tokens render as no background/foreground instead of feeding
17
+ // an empty color string to Ink.
18
+ return theme[color] || undefined;
16
19
  }
17
20
  /**
18
21
  * Theme-aware Box component that resolves theme color keys to raw colors
@@ -20,8 +20,8 @@ function resolveColor(color, theme) {
20
20
  color.startsWith('ansi:')) {
21
21
  return color;
22
22
  }
23
- // It's a theme key - resolve it
24
- return theme[color];
23
+ // It's a theme key - resolve it ('' means "no color" in that theme)
24
+ return theme[color] || undefined;
25
25
  }
26
26
  /**
27
27
  * Theme-aware Text component that resolves theme color keys to raw colors
@@ -5,6 +5,10 @@ type Props = {
5
5
  addMargin: boolean;
6
6
  /** True when Ctrl+O transcript/verbose mode is on — show the full text. */
7
7
  verbose: boolean;
8
+ /** True while the reasoning block is still streaming — the leading anchor
9
+ * becomes a rotating braille spinner (Kimi Code style) and settles back
10
+ * to the anchor once the step ends. */
11
+ streaming?: boolean;
8
12
  /** Streaming compact mode (thinkingFold=preview): a 3-row live ticker of
9
13
  * the model's latest reasoning lines instead of the full block —
10
14
  * kimicode-style constant height; the block never resizes mid-stream. */
@@ -16,12 +20,14 @@ type Props = {
16
20
  onClick?(): void;
17
21
  };
18
22
  /**
19
- * Thinking block: folded `∴ Thinking (ctrl+o to expand)`, expanded shows the
20
- * full reasoning text indented under `∴ Thinking…`, mirroring Claude Code's
21
- * `messages/AssistantThinkingMessage.tsx`. When the channel records the
22
- * reasoning duration, the label carries it (`∴ Thinking · 12s …`) — dsh-tui's
23
- * take on making thinking time visible in the transcript.
23
+ * Thinking block: folded `⚓ Thinking (ctrl+o to expand)`, expanded shows the
24
+ * full reasoning text indented under `⚓ Thinking…`. While the reasoning
25
+ * streams the leading mark is a rotating braille spinner (`⠋⠙⠹…`, Kimi Code
26
+ * style), settling back to the static anchor (`⚓`) once the turn ends. When
27
+ * the channel records the reasoning duration, the label carries it
28
+ * (`⚓ Thinking · 12s …`) — dsh-tui's take on making thinking time visible in
29
+ * the transcript.
24
30
  */
25
- export declare function AssistantThinkingMessage({ thinking, addMargin, verbose, preview, durationMs, isSelected, onClick, }: Props): React.ReactNode;
31
+ export declare function AssistantThinkingMessage({ thinking, addMargin, verbose, streaming, preview, durationMs, isSelected, onClick, }: Props): React.ReactNode;
26
32
  export {};
27
33
  //# sourceMappingURL=AssistantThinkingMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA2FzB"}
1
+ {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAmBzB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,SAAiB,EACjB,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAwGzB"}