@deepseek-harness-tui/dsh-tui 0.8.5 → 0.8.7
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/README.md +13 -3
- package/bin/dsh-tui.js +269 -218
- package/cordis.patch.yml +48 -22
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
- package/dsh-ecosystem-spec/registry/README.md +14 -14
- package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
- package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
- package/lib/types/cc/figures.d.ts +7 -0
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +24 -0
- package/lib/types/cc/markdown.d.ts.map +1 -1
- package/lib/types/cc/markdown.js +47 -14
- package/lib/types/cc/syntaxRuns.d.ts +16 -0
- package/lib/types/cc/syntaxRuns.d.ts.map +1 -0
- package/lib/types/cc/syntaxRuns.js +79 -0
- package/lib/types/cc/syntaxTheme.d.ts +12 -0
- package/lib/types/cc/syntaxTheme.d.ts.map +1 -0
- package/lib/types/cc/syntaxTheme.js +76 -0
- package/lib/types/commands.d.ts +14 -0
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +20 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts +19 -0
- package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -0
- package/lib/types/components/Chat/SubagentMessage.js +75 -0
- package/lib/types/components/EffortChargeGlyph.d.ts +26 -0
- package/lib/types/components/EffortChargeGlyph.d.ts.map +1 -0
- package/lib/types/components/EffortChargeGlyph.js +70 -0
- package/lib/types/components/EffortInputBorder.d.ts +36 -0
- package/lib/types/components/EffortInputBorder.d.ts.map +1 -0
- package/lib/types/components/EffortInputBorder.js +73 -0
- package/lib/types/components/EffortTierBadge.d.ts +26 -0
- package/lib/types/components/EffortTierBadge.d.ts.map +1 -0
- package/lib/types/components/EffortTierBadge.js +97 -0
- package/lib/types/components/HelpMenu.d.ts +8 -1
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +15 -4
- package/lib/types/components/LoadedContextPanel.js +1 -1
- package/lib/types/components/LogoV2.d.ts +3 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +2 -2
- package/lib/types/components/MessageList.d.ts +6 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +22 -13
- package/lib/types/components/ModelPicker.js +2 -2
- package/lib/types/components/PromptInput.d.ts +1 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +83 -18
- package/lib/types/components/SkillsPicker.js +2 -2
- package/lib/types/components/SplitDiffView.d.ts +2 -17
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +9 -162
- package/lib/types/components/StreamingMarkdown.js +1 -1
- package/lib/types/components/SubagentCard.d.ts +9 -0
- package/lib/types/components/SubagentCard.d.ts.map +1 -0
- package/lib/types/components/SubagentCard.js +26 -0
- package/lib/types/components/SubagentDashboard.d.ts +13 -0
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -0
- package/lib/types/components/SubagentDashboard.js +50 -0
- package/lib/types/components/SubagentDetailScene.d.ts +16 -0
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -0
- package/lib/types/components/SubagentDetailScene.js +141 -0
- package/lib/types/components/SyntaxText.d.ts +15 -0
- package/lib/types/components/SyntaxText.d.ts.map +1 -0
- package/lib/types/components/SyntaxText.js +34 -0
- package/lib/types/components/ThinkingToggle.d.ts +3 -10
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +4 -9
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +1 -1
- package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemedBox.js +4 -1
- package/lib/types/components/design-system/ThemedText.js +2 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +12 -6
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +37 -10
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -0
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +71 -18
- package/lib/types/components/messages/UserPromptMessage.d.ts +4 -6
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
- package/lib/types/components/messages/UserPromptMessage.js +19 -10
- package/lib/types/dsh-adapter/channel.d.ts +58 -2
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +337 -7
- package/lib/types/dsh-adapter/contract.d.ts +27 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +56 -10
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +9 -3
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +38 -0
- package/lib/types/dsh-adapter/shortcuts.js +3 -3
- package/lib/types/dsh-adapter/subagents.d.ts +87 -0
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -0
- package/lib/types/dsh-adapter/subagents.js +204 -0
- package/lib/types/herdr.d.ts +28 -0
- package/lib/types/herdr.d.ts.map +1 -0
- package/lib/types/herdr.js +133 -0
- package/lib/types/i18n.d.ts +215 -31
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +65 -14
- package/lib/types/ink/ink.d.ts +4 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +46 -15
- package/lib/types/minimalMode.d.ts +13 -0
- package/lib/types/minimalMode.d.ts.map +1 -0
- package/lib/types/minimalMode.js +17 -0
- package/lib/types/screens/Chat.d.ts +1 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +95 -45
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +6 -2
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
- package/lib/types/screens/TrajectoryScene.js +4 -2
- package/lib/types/theme.d.ts +20 -0
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +77 -23
- package/lib/types/tips.js +3 -3
- package/lib/types/trajectory/effortIgnition.d.ts +66 -0
- package/lib/types/trajectory/effortIgnition.d.ts.map +1 -0
- package/lib/types/trajectory/effortIgnition.js +142 -0
- package/lib/types/update.d.ts +18 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +73 -2
- package/lib/types/utils/execFileNoThrow.d.ts +3 -20
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +53 -32
- package/lib/types/utils/externalEditor.d.ts +12 -11
- package/lib/types/utils/externalEditor.d.ts.map +1 -1
- package/lib/types/utils/externalEditor.js +11 -11
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/command/LICENSE +21 -21
- package/node_modules/@dsh-std/command/README.md +26 -26
- package/node_modules/@dsh-std/command/README.zh.md +28 -28
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/command/package.json +22 -22
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/node_modules/@dsh-std/connection/README.md +42 -42
- package/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +20 -20
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/core/LICENSE +21 -21
- package/node_modules/@dsh-std/core/README.md +13 -13
- package/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/core/package.json +21 -21
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/node_modules/@dsh-std/manifest/README.md +5 -5
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/manifest/package.json +20 -20
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/messages/LICENSE +21 -21
- package/node_modules/@dsh-std/messages/README.md +5 -5
- package/node_modules/@dsh-std/messages/README.zh.md +7 -7
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/messages/package.json +20 -20
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/node_modules/@dsh-std/presentation/README.md +27 -27
- package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +25 -25
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/storage/LICENSE +21 -21
- package/node_modules/@dsh-std/storage/README.md +5 -5
- package/node_modules/@dsh-std/storage/README.zh.md +7 -7
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/storage/package.json +20 -20
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
- package/package.json +64 -58
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
|
@@ -2,154 +2,17 @@ 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 { highlightLines, syntaxThemeSignature } from '../cc/syntaxRuns.js';
|
|
8
|
+
// Backward-compatible re-export: repro scripts import chalkFromToken from
|
|
9
|
+
// this module's old home.
|
|
10
|
+
export { chalkFromToken } from '../cc/syntaxTheme.js';
|
|
11
|
+
export { parseAnsiRuns, highlightLines } from '../cc/syntaxRuns.js';
|
|
8
12
|
import { getTheme } from '../theme.js';
|
|
9
13
|
import { useTheme } from './design-system/ThemeProvider.js';
|
|
10
14
|
/** Replace tabs so width math and alignment hold (pi convention). */
|
|
11
15
|
const expandTabs = (text) => text.replaceAll('\t', ' ');
|
|
12
|
-
// --- 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
|
-
}
|
|
72
|
-
/** ANSI 16-color SGR codes → rgb() strings (the dark-ansi palette path). */
|
|
73
|
-
const ANSI16 = {
|
|
74
|
-
30: 'rgb(0,0,0)', 31: 'rgb(128,0,0)', 32: 'rgb(0,128,0)', 33: 'rgb(128,128,0)',
|
|
75
|
-
34: 'rgb(0,0,128)', 35: 'rgb(128,0,128)', 36: 'rgb(0,128,128)', 37: 'rgb(192,192,192)',
|
|
76
|
-
90: 'rgb(128,128,128)', 91: 'rgb(255,0,0)', 92: 'rgb(0,255,0)', 93: 'rgb(255,255,0)',
|
|
77
|
-
94: 'rgb(0,0,255)', 95: 'rgb(255,0,255)', 96: 'rgb(0,255,255)', 97: 'rgb(255,255,255)',
|
|
78
|
-
};
|
|
79
|
-
/** Parse a cli-highlight ANSI string into colored runs, preserving open
|
|
80
|
-
* spans across embedded newlines (multi-line strings/comments). Handles
|
|
81
|
-
* truecolor 38;2, 256-color 38;5 (tmux / FORCE_COLOR=2, issue #250 P1-1),
|
|
82
|
-
* and single-code 16-color SGR. */
|
|
83
|
-
export function parseAnsiRuns(text) {
|
|
84
|
-
const runs = [];
|
|
85
|
-
let color;
|
|
86
|
-
let rest = text;
|
|
87
|
-
// eslint-disable-next-line no-control-regex -- parsing SGR is the point
|
|
88
|
-
const sgr = /\x1b\[([0-9;]+)m/;
|
|
89
|
-
while (rest.length > 0) {
|
|
90
|
-
const match = sgr.exec(rest);
|
|
91
|
-
const chunk = match === null ? rest : rest.slice(0, match.index);
|
|
92
|
-
if (chunk !== '')
|
|
93
|
-
runs.push(color === undefined ? { text: chunk } : { text: chunk, color });
|
|
94
|
-
if (match === null)
|
|
95
|
-
break;
|
|
96
|
-
const codes = match[1].split(';').map(Number);
|
|
97
|
-
if (codes.includes(0) || codes.includes(39))
|
|
98
|
-
color = undefined;
|
|
99
|
-
else if (codes[0] === 38 && codes[1] === 2 && codes.length >= 5) {
|
|
100
|
-
color = `rgb(${codes[2]},${codes[3]},${codes[4]})`;
|
|
101
|
-
}
|
|
102
|
-
else if (codes[0] === 38 && codes[1] === 5 && codes.length >= 3) {
|
|
103
|
-
color = `ansi256(${codes[2]})`;
|
|
104
|
-
}
|
|
105
|
-
else if (codes.length === 1 && ANSI16[codes[0]] !== undefined) {
|
|
106
|
-
color = ANSI16[codes[0]];
|
|
107
|
-
}
|
|
108
|
-
rest = rest.slice(match.index + match[0].length);
|
|
109
|
-
}
|
|
110
|
-
return runs;
|
|
111
|
-
}
|
|
112
|
-
/** Split flat runs into per-line run arrays at embedded newlines. */
|
|
113
|
-
function splitRunsToLines(runs) {
|
|
114
|
-
const lines = [[]];
|
|
115
|
-
for (const run of runs) {
|
|
116
|
-
const parts = run.text.split('\n');
|
|
117
|
-
for (let i = 0; i < parts.length; i++) {
|
|
118
|
-
if (i > 0)
|
|
119
|
-
lines.push([]);
|
|
120
|
-
if (parts[i] !== '') {
|
|
121
|
-
lines[lines.length - 1].push(run.color === undefined ? { text: parts[i] } : { text: parts[i], color: run.color });
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return lines;
|
|
126
|
-
}
|
|
127
|
-
/** Whole-hunk syntax runs per line, cached per (theme signature + language
|
|
128
|
-
* + text): one entry survives any amount of card re-rendering, and the
|
|
129
|
-
* palette change invalidates it (issue #250, P1-2 + P2-8). */
|
|
130
|
-
const syntaxCache = new Map();
|
|
131
|
-
const SYNTAX_CACHE_MAX = 40;
|
|
132
|
-
export function highlightLines(text, language, hl, chTheme, themeSig) {
|
|
133
|
-
if (hl === null || chTheme === undefined || language === undefined)
|
|
134
|
-
return undefined;
|
|
135
|
-
if (text === '' || !hl.supportsLanguage(language))
|
|
136
|
-
return undefined;
|
|
137
|
-
const key = `${themeSig}${language}${text}`;
|
|
138
|
-
const cached = syntaxCache.get(key);
|
|
139
|
-
if (cached !== undefined)
|
|
140
|
-
return cached;
|
|
141
|
-
let lines;
|
|
142
|
-
try {
|
|
143
|
-
lines = splitRunsToLines(parseAnsiRuns(hl.highlight(text, { language, theme: chTheme })));
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
if (syntaxCache.size >= SYNTAX_CACHE_MAX)
|
|
149
|
-
syntaxCache.clear();
|
|
150
|
-
syntaxCache.set(key, lines);
|
|
151
|
-
return lines;
|
|
152
|
-
}
|
|
153
16
|
/**
|
|
154
17
|
* Merge syntax runs with word-diff change flags over the same string: both
|
|
155
18
|
* partition it, so an offset sweep yields runs carrying a syntax color AND
|
|
@@ -360,24 +223,8 @@ export function SplitDiffView({ diffs, width, maxRows, verbose, toolBackground =
|
|
|
360
223
|
const [themeName] = useTheme();
|
|
361
224
|
// Resolved-palette signature: covers dark→light, light→dark, AND the
|
|
362
225
|
// `auto` base flip where the name never changes (issue #250, P1-2).
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
return Object.values(SYNTAX_CLASS_TO_TOKEN)
|
|
366
|
-
.map(key => theme[key] ?? '')
|
|
367
|
-
.join('|');
|
|
368
|
-
}, [themeName]);
|
|
369
|
-
const chTheme = React.useMemo(() => {
|
|
370
|
-
const theme = getTheme(themeName);
|
|
371
|
-
const out = {};
|
|
372
|
-
for (const [tokenClass, tokenKey] of Object.entries(SYNTAX_CLASS_TO_TOKEN)) {
|
|
373
|
-
const value = theme[tokenKey];
|
|
374
|
-
if (value !== undefined)
|
|
375
|
-
out[tokenClass] = chalkFromToken(value);
|
|
376
|
-
}
|
|
377
|
-
return out;
|
|
378
|
-
// themeSig changes exactly when any syntax token's resolved value does.
|
|
379
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
380
|
-
}, [themeSig]);
|
|
226
|
+
const syntaxTheme = React.useMemo(() => getTheme(themeName), [themeName]);
|
|
227
|
+
const themeSig = React.useMemo(() => syntaxThemeSignature(syntaxTheme), [syntaxTheme]);
|
|
381
228
|
// Alignment is text-only and capped BEFORE styling: the highlighter and
|
|
382
229
|
// word-diff work lands only on the visible slice (issue #250, P2-8).
|
|
383
230
|
const rows = [];
|
|
@@ -402,8 +249,8 @@ export function SplitDiffView({ diffs, width, maxRows, verbose, toolBackground =
|
|
|
402
249
|
const fileSyntax = diffs.map(diff => {
|
|
403
250
|
const language = extname(diff.path).replace(/^\./, '') || undefined;
|
|
404
251
|
return {
|
|
405
|
-
old: highlightLines(expandTabs(diff.oldText ?? ''), language, hl,
|
|
406
|
-
next: highlightLines(expandTabs(diff.newText), language, hl,
|
|
252
|
+
old: highlightLines(expandTabs(diff.oldText ?? ''), language, hl, syntaxTheme, themeSig),
|
|
253
|
+
next: highlightLines(expandTabs(diff.newText), language, hl, syntaxTheme, themeSig),
|
|
407
254
|
};
|
|
408
255
|
});
|
|
409
256
|
return (_jsxs(Box, { flexDirection: "column", width: paneWidth * 2 + 1, children: [visible.map((row, index) => {
|
|
@@ -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:
|
|
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
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SubagentState } from '../dsh-adapter/subagents.js';
|
|
3
|
+
export interface SubagentCardProps {
|
|
4
|
+
subagent: SubagentState;
|
|
5
|
+
focused?: boolean;
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function SubagentCard({ subagent, focused, onClick }: SubagentCardProps): React.ReactNode;
|
|
9
|
+
//# sourceMappingURL=SubagentCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAShE,MAAM,WAAW,iBAAiB;IAAG,QAAQ,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE;AAEvG,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CA4B/F"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from '../ui.js';
|
|
3
|
+
import { t } from '../i18n.js';
|
|
4
|
+
import { isMinimalMode } from '../minimalMode.js';
|
|
5
|
+
function formatDuration(ms) {
|
|
6
|
+
const seconds = Math.floor(ms / 1000);
|
|
7
|
+
return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m${seconds % 60}s`;
|
|
8
|
+
}
|
|
9
|
+
export function SubagentCard({ subagent, focused, onClick }) {
|
|
10
|
+
const running = subagent.status === 'running' || subagent.status === 'starting';
|
|
11
|
+
const elapsed = subagent.completedAt ? subagent.completedAt - subagent.startedAt : Date.now() - subagent.startedAt;
|
|
12
|
+
const total = subagent.tokens?.total ?? ((subagent.tokens?.input ?? 0) + (subagent.tokens?.output ?? 0) || 0);
|
|
13
|
+
// Live preview: the newest streamed line rides under the header while the
|
|
14
|
+
// subagent runs, then folds away — the dashboard stays one line per settled
|
|
15
|
+
// subagent.
|
|
16
|
+
const liveLine = running ? subagent.output[subagent.output.length - 1] : undefined;
|
|
17
|
+
const minimal = isMinimalMode();
|
|
18
|
+
const glyph = running ? (minimal ? '·' : '🟡')
|
|
19
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? (minimal ? '×' : '🔴')
|
|
20
|
+
: (minimal ? '✓' : '🟢');
|
|
21
|
+
const glyphColor = minimal ? undefined
|
|
22
|
+
: running ? 'warning'
|
|
23
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? 'error'
|
|
24
|
+
: 'success';
|
|
25
|
+
return _jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, onClick: onClick, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsx(Text, { bold: true, color: focused ? 'claude' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${total || '—'} tok · ${subagent.toolCalls.length} tools` })] })] }), liveLine && _jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${liveLine}` })] });
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SubagentState } from '../dsh-adapter/subagents.js';
|
|
3
|
+
export interface SubagentDashboardProps {
|
|
4
|
+
subagents: SubagentState[];
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onSelect?: (agentId: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* SubagentDashboard — overlay panel showing all active/recent subagents.
|
|
10
|
+
* Keyboard: up/down to navigate, Enter to view detail, Esc to close.
|
|
11
|
+
*/
|
|
12
|
+
export declare function SubagentDashboard({ subagents, onClose, onSelect }: SubagentDashboardProps): React.ReactNode;
|
|
13
|
+
//# sourceMappingURL=SubagentDashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAMhE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,QAAQ,EACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,SAAS,CAoG1C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text, useInput, ScrollBox, useTerminalSize } from '../ui.js';
|
|
4
|
+
import { SubagentCard } from './SubagentCard.js';
|
|
5
|
+
import { t } from '../i18n.js';
|
|
6
|
+
import { Divider } from './design-system/Divider.js';
|
|
7
|
+
import { isPlainReturnInput } from '../utils/modifiers.js';
|
|
8
|
+
/**
|
|
9
|
+
* SubagentDashboard — overlay panel showing all active/recent subagents.
|
|
10
|
+
* Keyboard: up/down to navigate, Enter to view detail, Esc to close.
|
|
11
|
+
*/
|
|
12
|
+
export function SubagentDashboard({ subagents, onClose, onSelect }) {
|
|
13
|
+
const [focusIndex, setFocusIndex] = React.useState(0);
|
|
14
|
+
const scrollRef = React.useRef(null);
|
|
15
|
+
const { rows, columns } = useTerminalSize();
|
|
16
|
+
useInput((input, key, event) => {
|
|
17
|
+
if (key.escape || (key.ctrl && input === 'c')) {
|
|
18
|
+
event.stopImmediatePropagation();
|
|
19
|
+
onClose();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (key.upArrow) {
|
|
23
|
+
event.stopImmediatePropagation();
|
|
24
|
+
setFocusIndex(i => Math.max(0, i - 1));
|
|
25
|
+
scrollRef.current?.scrollBy(-3);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (key.downArrow) {
|
|
29
|
+
event.stopImmediatePropagation();
|
|
30
|
+
setFocusIndex(i => Math.min(subagents.length - 1, i + 1));
|
|
31
|
+
scrollRef.current?.scrollBy(3);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (isPlainReturnInput(input, key) && onSelect) {
|
|
35
|
+
event.stopImmediatePropagation();
|
|
36
|
+
const selected = subagents[focusIndex];
|
|
37
|
+
if (selected)
|
|
38
|
+
onSelect(selected.agentId);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Consume all input while dashboard is open
|
|
42
|
+
event.stopImmediatePropagation();
|
|
43
|
+
});
|
|
44
|
+
const running = subagents.filter(s => s.status === 'running').length;
|
|
45
|
+
const completed = subagents.filter(s => s.status === 'completed').length;
|
|
46
|
+
const failed = subagents.filter(s => s.status === 'failed').length;
|
|
47
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsx(Divider, { color: "claude", title: t('subagent-dashboard-title'), padding: 4 }), _jsxs(Box, { flexDirection: "row", gap: 3, marginTop: 1, marginBottom: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "claude", children: running }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-running')] })] }), _jsxs(Text, { children: [_jsx(Text, { color: "success", children: completed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-completed')] })] }), failed > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "error", children: failed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-failed')] })] }))] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(10, rows - 10), marginTop: 1, children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: subagents.length === 0 ? (_jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: Math.max(2, Math.floor((rows - 16) / 3)), children: [_jsx(Text, { dimColor: true, children: '○' }), _jsx(Text, { dimColor: true, children: t('subagent-none') }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-empty-hint') }) })] })) : (subagents.map((subagent, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(SubagentCard, { subagent: subagent, focused: index === focusIndex }), index < subagents.length - 1 && (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }))] }, subagent.agentId)))) }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsx(Box, { marginTop: 0, children: _jsx(Text, { dimColor: true, children: onSelect
|
|
48
|
+
? t('subagent-dashboard-hint-detail')
|
|
49
|
+
: t('subagent-dashboard-hint-basic') }) })] }));
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SubagentState } from '../dsh-adapter/subagents.js';
|
|
3
|
+
export interface SubagentDetailSceneProps {
|
|
4
|
+
subagent: SubagentState;
|
|
5
|
+
onBack: () => void;
|
|
6
|
+
onInterrupt?: (agentId: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* SubagentDetailScene — full-screen paged detail view for one subagent.
|
|
10
|
+
* Header block (identity + stats) stays fixed; the body pages through
|
|
11
|
+
* 摘要 / 输出 / 工具 with ←/→. Follow-up delivery was removed: the official
|
|
12
|
+
* seam only accepts continuable children, and one-shot spawn children are
|
|
13
|
+
* disposed at settlement, so the affordance would be a dead control.
|
|
14
|
+
*/
|
|
15
|
+
export declare function SubagentDetailScene({ subagent, onBack, onInterrupt, }: SubagentDetailSceneProps): React.ReactNode;
|
|
16
|
+
//# sourceMappingURL=SubagentDetailScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentDetailScene.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDetailScene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAsGhE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,aAAa,CAAA;IACvB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,EAAE,wBAAwB,GAAG,KAAK,CAAC,SAAS,CA+L5C"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text, useInput, ScrollBox, useTerminalSize } from '../ui.js';
|
|
4
|
+
import { t } from '../i18n.js';
|
|
5
|
+
import { Divider } from './design-system/Divider.js';
|
|
6
|
+
import { isPlainReturnInput } from '../utils/modifiers.js';
|
|
7
|
+
import { toolNameColor } from './messages/AssistantToolUseMessage.js';
|
|
8
|
+
import { getCliHighlightPromise } from '../cc/cliHighlight.js';
|
|
9
|
+
import { isMinimalMode } from '../minimalMode.js';
|
|
10
|
+
function formatDuration(ms) {
|
|
11
|
+
if (ms < 1000)
|
|
12
|
+
return `${ms}ms`;
|
|
13
|
+
if (ms < 60000)
|
|
14
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
15
|
+
const min = Math.floor(ms / 60000);
|
|
16
|
+
const sec = Math.floor((ms % 60000) / 1000);
|
|
17
|
+
return `${min}m${sec}s`;
|
|
18
|
+
}
|
|
19
|
+
function formatTimestamp(ts) {
|
|
20
|
+
return new Date(ts).toLocaleTimeString();
|
|
21
|
+
}
|
|
22
|
+
function statusGlyph(status) {
|
|
23
|
+
const minimal = isMinimalMode();
|
|
24
|
+
if (status === 'completed')
|
|
25
|
+
return { glyph: minimal ? '✓' : '🟢', color: minimal ? undefined : 'success', label: 'done' };
|
|
26
|
+
if (status === 'failed')
|
|
27
|
+
return { glyph: minimal ? '×' : '🔴', color: minimal ? undefined : 'error', label: 'failed' };
|
|
28
|
+
if (status === 'cancelled')
|
|
29
|
+
return { glyph: minimal ? '×' : '🔴', color: minimal ? undefined : 'error', label: 'cancelled' };
|
|
30
|
+
return { glyph: minimal ? '·' : '🟡', color: minimal ? undefined : 'warning', label: 'running' };
|
|
31
|
+
}
|
|
32
|
+
const PAGES = ['summary', 'output', 'tools'];
|
|
33
|
+
/** One label/value row of the summary stats card. */
|
|
34
|
+
function StatRow({ label, children }) {
|
|
35
|
+
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 14, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: label }) }), _jsx(Box, { flexDirection: "row", flexGrow: 1, children: children })] }));
|
|
36
|
+
}
|
|
37
|
+
/** Two-column key/value stats grid (Kimi Code settled summary style). */
|
|
38
|
+
function StatGrid({ subagent, totalTokens, elapsed, statusLabel, statusColor }) {
|
|
39
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatRow, { label: t('subagent-status-label'), children: _jsx(Text, { color: statusColor, children: statusLabel }) }), _jsx(StatRow, { label: t('subagent-model'), children: _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }) }), _jsx(StatRow, { label: t('subagent-duration'), children: _jsx(Text, { children: formatDuration(elapsed) }) }), _jsx(StatRow, { label: "tokens", children: _jsxs(Text, { children: [totalTokens || '—', subagent.tokens?.input !== undefined ? ` (in ${subagent.tokens.input} · out ${subagent.tokens.output ?? 0})` : ''] }) }), _jsx(StatRow, { label: t('subagent-tools'), children: _jsx(Text, { children: subagent.toolCalls.length }) }), _jsx(StatRow, { label: t('subagent-started'), children: _jsx(Text, { children: formatTimestamp(subagent.startedAt) }) }), subagent.completedAt !== undefined && (_jsx(StatRow, { label: t('subagent-completed'), children: _jsx(Text, { children: formatTimestamp(subagent.completedAt) }) }))] }));
|
|
40
|
+
}
|
|
41
|
+
/** Tool args line: JSON-looking args get cli-highlight syntax colors (loaded
|
|
42
|
+
* lazily through the shared promise); anything else stays a dim flat line. */
|
|
43
|
+
function JsonArgsText({ raw }) {
|
|
44
|
+
const flat = raw.replace(/\s+/g, ' ').trim();
|
|
45
|
+
const json = flat.startsWith('{') || flat.startsWith('[');
|
|
46
|
+
const [highlighted, setHighlighted] = React.useState(null);
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
if (!json)
|
|
49
|
+
return;
|
|
50
|
+
let alive = true;
|
|
51
|
+
void getCliHighlightPromise().then(cli => {
|
|
52
|
+
if (!alive || cli === null)
|
|
53
|
+
return;
|
|
54
|
+
try {
|
|
55
|
+
setHighlighted(cli.highlight(flat, { language: 'json' }));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Not parseable JSON after all — keep the dim fallback.
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return () => { alive = false; };
|
|
62
|
+
}, [flat, json]);
|
|
63
|
+
if (json && highlighted !== null)
|
|
64
|
+
return _jsx(Text, { wrap: "wrap", children: highlighted });
|
|
65
|
+
return _jsx(Text, { dimColor: true, wrap: "wrap", children: flat });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* SubagentDetailScene — full-screen paged detail view for one subagent.
|
|
69
|
+
* Header block (identity + stats) stays fixed; the body pages through
|
|
70
|
+
* 摘要 / 输出 / 工具 with ←/→. Follow-up delivery was removed: the official
|
|
71
|
+
* seam only accepts continuable children, and one-shot spawn children are
|
|
72
|
+
* disposed at settlement, so the affordance would be a dead control.
|
|
73
|
+
*/
|
|
74
|
+
export function SubagentDetailScene({ subagent, onBack, onInterrupt, }) {
|
|
75
|
+
const scrollRef = React.useRef(null);
|
|
76
|
+
const { rows, columns } = useTerminalSize();
|
|
77
|
+
const [page, setPage] = React.useState('summary');
|
|
78
|
+
const isRunning = subagent.status === 'running' || subagent.status === 'starting';
|
|
79
|
+
const elapsed = subagent.completedAt ? subagent.completedAt - subagent.startedAt : Date.now() - subagent.startedAt;
|
|
80
|
+
const info = statusGlyph(subagent.status);
|
|
81
|
+
const totalTokens = subagent.tokens?.total ?? ((subagent.tokens?.input ?? 0) + (subagent.tokens?.output ?? 0) || 0);
|
|
82
|
+
const pageIndex = PAGES.indexOf(page);
|
|
83
|
+
const turnPage = (delta) => {
|
|
84
|
+
const next = (pageIndex + delta + PAGES.length) % PAGES.length;
|
|
85
|
+
setPage(PAGES[next]);
|
|
86
|
+
scrollRef.current?.scrollTo?.(0);
|
|
87
|
+
};
|
|
88
|
+
// tail -f: while the subagent runs and the output page is showing, follow
|
|
89
|
+
// the newest streamed line. Page switches or settlement stop the follow so
|
|
90
|
+
// manual ↑ scrolling wins.
|
|
91
|
+
const outputLength = subagent.outputEvents.length;
|
|
92
|
+
React.useEffect(() => {
|
|
93
|
+
if (page !== 'output' || !isRunning)
|
|
94
|
+
return;
|
|
95
|
+
scrollRef.current?.scrollToBottom();
|
|
96
|
+
}, [page, isRunning, outputLength]);
|
|
97
|
+
useInput((input, key, event) => {
|
|
98
|
+
if (key.escape || (key.ctrl && input === 'c')) {
|
|
99
|
+
event.stopImmediatePropagation();
|
|
100
|
+
onBack();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (key.leftArrow) {
|
|
104
|
+
event.stopImmediatePropagation();
|
|
105
|
+
turnPage(-1);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (key.rightArrow) {
|
|
109
|
+
event.stopImmediatePropagation();
|
|
110
|
+
turnPage(1);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (key.upArrow) {
|
|
114
|
+
event.stopImmediatePropagation();
|
|
115
|
+
scrollRef.current?.scrollBy(-3);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (key.downArrow) {
|
|
119
|
+
event.stopImmediatePropagation();
|
|
120
|
+
scrollRef.current?.scrollBy(3);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (input.toLowerCase() === 'x' && isRunning && onInterrupt) {
|
|
124
|
+
event.stopImmediatePropagation();
|
|
125
|
+
onInterrupt(subagent.agentId);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (isPlainReturnInput(input, key)) {
|
|
129
|
+
event.stopImmediatePropagation();
|
|
130
|
+
onBack();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
event.stopImmediatePropagation();
|
|
134
|
+
});
|
|
135
|
+
const tab = (name, label) => {
|
|
136
|
+
const active = page === name;
|
|
137
|
+
return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: active ? 'claude' : undefined, bold: active, inverse: active, children: ` ${label} ` }), _jsx(Text, { dimColor: true, children: name === PAGES[PAGES.length - 1] ? '' : '│' })] }, name));
|
|
138
|
+
};
|
|
139
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, bold: true, children: info.glyph }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label })] }), _jsxs(Text, { children: [_jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${totalTokens || '—'} tok · ${subagent.toolCalls.length} tools` })] }), _jsxs(Text, { dimColor: true, children: [`${t('subagent-started')} ${formatTimestamp(subagent.startedAt)}`
|
|
140
|
+
+ (subagent.completedAt ? ` · ${t('subagent-completed')} ${formatTimestamp(subagent.completedAt)}` : ''), ` · id ${subagent.agentId}`] }), subagent.error && (_jsx(Box, { marginTop: 0, children: _jsx(Text, { color: "error", wrap: "wrap", children: `${t('subagent-error-label')}: ${subagent.error}` }) })), _jsxs(Box, { flexDirection: "row", gap: 0, marginTop: 1, children: [tab('summary', t('subagent-tab-summary')), tab('output', t('subagent-output-label')), tab('tools', t('subagent-tools')), _jsx(Text, { dimColor: true, children: ` ${pageIndex + 1}/${PAGES.length}` })] }), _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }), _jsx(Box, { flexDirection: "column", paddingX: 1, maxHeight: Math.max(10, rows - 14), children: _jsxs(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: [page === 'summary' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatGrid, { subagent: subagent, totalTokens: totalTokens, elapsed: elapsed, statusLabel: info.label, statusColor: info.color }), subagent.summary && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: '─ summary ' }), _jsx(Text, { wrap: "wrap", children: subagent.summary })] })), !subagent.summary && (_jsx(Text, { dimColor: true, children: isRunning ? t('subagent-no-output') : t('subagent-no-summary') }))] })), page === 'output' && (subagent.outputEvents.length === 0 && subagent.output.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-output') })) : (subagent.outputEvents.map((line, index) => (_jsxs(Text, { wrap: "wrap", dimColor: line.kind === 'thinking' || line.kind === 'system', color: line.kind === 'error' ? 'error' : undefined, children: [line.kind === 'thinking' ? ' ⌁ ' : ' ', line.text, !line.settled && isRunning ? ' ▍' : ''] }, index))))), page === 'tools' && (subagent.toolCalls.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-tools') })) : (subagent.toolCalls.map((tool, index) => (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: tool.status === 'failed' ? 'error' : tool.status === 'running' ? 'warning' : 'success', children: tool.status === 'running' ? '·' : tool.status === 'failed' ? '×' : '✓' }), _jsx(Text, { color: toolNameColor(tool.name), children: tool.name }), tool.endedAt && _jsx(Text, { dimColor: true, children: formatDuration(tool.endedAt - tool.startedAt) })] }), tool.argsPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(JsonArgsText, { raw: tool.argsPreview }) })), tool.resultPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: `⎿ ${tool.resultPreview}` }) })), tool.error && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { color: "error", wrap: "wrap", children: tool.error }) }))] }, tool.id ?? index)))))] }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsx(Box, { marginTop: 0, children: _jsxs(Text, { dimColor: true, children: [`←/→ ${t('subagent-hint-page')} · ↑/↓ ${t('subagent-hint-scroll')}`, isRunning && onInterrupt ? ' · X interrupt' : '', ` · Esc ${t('subagent-hint-back')}`] }) })] }));
|
|
141
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Color } from '../ink/styles.js';
|
|
3
|
+
type Props = {
|
|
4
|
+
readonly text: string;
|
|
5
|
+
readonly language?: string;
|
|
6
|
+
/** Complete payload used for lexing; text is the visible line. */
|
|
7
|
+
readonly sourceText?: string;
|
|
8
|
+
readonly lineIndex?: number;
|
|
9
|
+
readonly color?: Color;
|
|
10
|
+
readonly dimColor?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Async nested Text renderer. Lexes the complete payload before splitting. */
|
|
13
|
+
export declare function SyntaxText({ text, language, sourceText, lineIndex, color, dimColor }: Props): React.ReactNode;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=SyntaxText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyntaxText.d.ts","sourceRoot":"","sources":["../../../src/components/SyntaxText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAM7C,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAiB,EAAE,SAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAgCxH"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Text } from '../ui.js';
|
|
4
|
+
import { getCliHighlightPromise } from '../cc/cliHighlight.js';
|
|
5
|
+
import { highlightLines, syntaxThemeSignature } from '../cc/syntaxRuns.js';
|
|
6
|
+
import { getTheme } from '../theme.js';
|
|
7
|
+
import { useTheme } from './design-system/ThemeProvider.js';
|
|
8
|
+
/** Async nested Text renderer. Lexes the complete payload before splitting. */
|
|
9
|
+
export function SyntaxText({ text, language, sourceText = text, lineIndex = 0, color, dimColor }) {
|
|
10
|
+
const [highlighter, setHighlighter] = React.useState(null);
|
|
11
|
+
const [themeName] = useTheme();
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
let mounted = true;
|
|
14
|
+
void getCliHighlightPromise().then(value => { if (mounted)
|
|
15
|
+
setHighlighter(value); });
|
|
16
|
+
return () => { mounted = false; };
|
|
17
|
+
}, []);
|
|
18
|
+
const theme = React.useMemo(() => getTheme(themeName), [themeName]);
|
|
19
|
+
const themeSig = React.useMemo(() => syntaxThemeSignature(theme), [theme]);
|
|
20
|
+
const syntax = React.useMemo(() => highlightLines(sourceText, language, highlighter, theme, themeSig), [sourceText, language, highlighter, theme, themeSig]);
|
|
21
|
+
const runs = syntax?.[lineIndex];
|
|
22
|
+
if (runs === undefined || color !== undefined || dimColor) {
|
|
23
|
+
return _jsx(Text, { color: color, dimColor: dimColor, children: text === '' ? ' ' : text });
|
|
24
|
+
}
|
|
25
|
+
let remaining = text.length;
|
|
26
|
+
const visibleRuns = runs.flatMap(run => {
|
|
27
|
+
if (remaining <= 0)
|
|
28
|
+
return [];
|
|
29
|
+
const visible = run.text.slice(0, remaining);
|
|
30
|
+
remaining -= visible.length;
|
|
31
|
+
return visible === '' ? [] : [{ ...run, text: visible }];
|
|
32
|
+
});
|
|
33
|
+
return (_jsx(Text, { children: visibleRuns.length === 0 ? text : visibleRuns.map((run, index) => (_jsx(Text, { color: run.color, children: run.text }, index))) }));
|
|
34
|
+
}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* The `/thinking` dialog
|
|
4
|
-
*
|
|
5
|
-
* (with CC's option descriptions), and the Enter/Esc hint line.
|
|
6
|
-
*
|
|
7
|
-
* When `confirmationPending` is set (mid-conversation toggle), the select is
|
|
8
|
-
* replaced by CC's yellow warning block and the hint line becomes
|
|
9
|
-
* Enter confirm / Esc cancel; keyboard handling lives in the caller (Chat).
|
|
3
|
+
* The `/thinking` display dialog: a permission-colored Pane with a bold
|
|
4
|
+
* title, the Shown/Hidden select, and the Enter/Esc hint line.
|
|
10
5
|
*/
|
|
11
|
-
export declare function ThinkingToggle({ currentValue, focusIndex,
|
|
6
|
+
export declare function ThinkingToggle({ currentValue, focusIndex, }: {
|
|
12
7
|
currentValue: boolean;
|
|
13
8
|
focusIndex: number;
|
|
14
|
-
/** Set while a mid-conversation toggle awaits Enter confirmation. */
|
|
15
|
-
confirmationPending: boolean | null;
|
|
16
9
|
}): React.ReactNode;
|
|
17
10
|
//# sourceMappingURL=ThinkingToggle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThinkingToggle.d.ts","sourceRoot":"","sources":["../../../src/components/ThinkingToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB
|
|
1
|
+
{"version":3,"file":"ThinkingToggle.d.ts","sourceRoot":"","sources":["../../../src/components/ThinkingToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,UAAU,GACX,EAAE;IACD,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CAsClB"}
|
|
@@ -5,15 +5,10 @@ import { Pane } from './design-system/Pane.js';
|
|
|
5
5
|
import { Select } from './Select.js';
|
|
6
6
|
import { HintLine } from './design-system/HintLine.js';
|
|
7
7
|
/**
|
|
8
|
-
* The `/thinking` dialog
|
|
9
|
-
*
|
|
10
|
-
* (with CC's option descriptions), and the Enter/Esc hint line.
|
|
11
|
-
*
|
|
12
|
-
* When `confirmationPending` is set (mid-conversation toggle), the select is
|
|
13
|
-
* replaced by CC's yellow warning block and the hint line becomes
|
|
14
|
-
* Enter confirm / Esc cancel; keyboard handling lives in the caller (Chat).
|
|
8
|
+
* The `/thinking` display dialog: a permission-colored Pane with a bold
|
|
9
|
+
* title, the Shown/Hidden select, and the Enter/Esc hint line.
|
|
15
10
|
*/
|
|
16
|
-
export function ThinkingToggle({ currentValue, focusIndex,
|
|
11
|
+
export function ThinkingToggle({ currentValue, focusIndex, }) {
|
|
17
12
|
const options = [
|
|
18
13
|
{
|
|
19
14
|
value: 'true',
|
|
@@ -26,5 +21,5 @@ export function ThinkingToggle({ currentValue, focusIndex, confirmationPending,
|
|
|
26
21
|
description: t('thinking-disabled-desc'),
|
|
27
22
|
},
|
|
28
23
|
];
|
|
29
|
-
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('thinking-title') }), _jsx(Text, { dimColor: true, children: t('thinking-subtitle') })] }),
|
|
24
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('thinking-title') }), _jsx(Text, { dimColor: true, children: t('thinking-subtitle') })] }), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsx(Select, { options: options, focusIndex: focusIndex, selectedValue: currentValue ? 'true' : 'false', visibleOptionCount: 2 }) })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-confirm-exit') }) })] }));
|
|
30
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7C,MAAM,MAAM,aAAa,GAAG;IAC1B;qDACiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB;uDACmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAA;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAa,EACb,QAAgB,EAChB,aAAa,GACd,EAAE,aAAa,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"ListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7C,MAAM,MAAM,aAAa,GAAG;IAC1B;qDACiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB;uDACmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAA;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAa,EACb,QAAgB,EAChB,aAAa,GACd,EAAE,aAAa,GAAG,KAAK,CAAC,SAAS,CAwEjC"}
|
|
@@ -54,7 +54,7 @@ export function ListItem({ isFocused, isSelected = false, children, description,
|
|
|
54
54
|
// 非 Fragment 的 element(如调用方自己的 <Text>)保留原样——其子树高度
|
|
55
55
|
// 由调用方负责。
|
|
56
56
|
const flatChildren = flattenDeep(children);
|
|
57
|
-
return (_jsxs(Box, { ref: cursorRef, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [renderIndicator(), styled ? (_jsx(Text, { color: getTextColor(), dimColor: disabled, wrap: "truncate", children: flatChildren })) : (flatChildren), isSelected && !disabled && _jsx(Text, { color: "success", children: TICK })] }), description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "inactive", wrap: "truncate", children: flattenLine(description) }) }))] }));
|
|
57
|
+
return (_jsxs(Box, { ref: cursorRef, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", gap: 1, height: 1, flexShrink: 0, overflow: "hidden", width: "100%", children: [renderIndicator(), styled ? (_jsx(Text, { color: getTextColor(), dimColor: disabled, wrap: "truncate-end", children: flatChildren })) : (flatChildren), isSelected && !disabled && _jsx(Text, { color: "success", children: TICK })] }), description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "inactive", wrap: "truncate", children: flattenLine(description) }) }))] }));
|
|
58
58
|
}
|
|
59
59
|
/** 单行化:内嵌换行折叠为空格(行尾/行首换行随之消除)。 */
|
|
60
60
|
function flattenLine(s) {
|
|
@@ -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;
|
|
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"}
|