@deepseek-harness-tui/dsh-tui 0.8.8 → 0.9.0
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 +27 -8
- package/bin/dsh-tui.js +1 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +4 -2
- package/lib/types/components/ActivityPicker.d.ts +4 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +2 -2
- package/lib/types/components/BtwPanel.d.ts.map +1 -1
- package/lib/types/components/BtwPanel.js +1 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts +2 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -1
- package/lib/types/components/Chat/SubagentMessage.js +11 -3
- package/lib/types/components/CommandSuggestions.d.ts +21 -4
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +41 -14
- package/lib/types/components/EffortSlider.d.ts +4 -1
- package/lib/types/components/EffortSlider.d.ts.map +1 -1
- package/lib/types/components/EffortSlider.js +4 -2
- package/lib/types/components/ExtensionDialog.js +6 -2
- package/lib/types/components/FileSuggestions.d.ts +24 -7
- package/lib/types/components/FileSuggestions.d.ts.map +1 -1
- package/lib/types/components/FileSuggestions.js +39 -12
- package/lib/types/components/GoalTodoPanel.d.ts +26 -2
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/GoalTodoPanel.js +86 -17
- package/lib/types/components/HelpMenu.d.ts +7 -1
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +12 -4
- package/lib/types/components/HistorySearchDialog.d.ts +4 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +2 -2
- package/lib/types/components/LangPicker.d.ts +14 -0
- package/lib/types/components/LangPicker.d.ts.map +1 -0
- package/lib/types/components/LangPicker.js +17 -0
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +3 -1
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +12 -3
- package/lib/types/components/MessageList.d.ts +43 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +553 -41
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +2 -2
- package/lib/types/components/PermissionsPicker.d.ts +21 -0
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
- package/lib/types/components/PermissionsPicker.js +27 -0
- package/lib/types/components/PlanPicker.d.ts +15 -0
- package/lib/types/components/PlanPicker.d.ts.map +1 -0
- package/lib/types/components/PlanPicker.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +4 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -2
- package/lib/types/components/PromptInput.d.ts +4 -3
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +248 -29
- package/lib/types/components/RewindPicker.d.ts +12 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +6 -4
- package/lib/types/components/ScrollbarGutter.d.ts +28 -0
- package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
- package/lib/types/components/ScrollbarGutter.js +68 -0
- package/lib/types/components/Select.d.ts +8 -1
- package/lib/types/components/Select.d.ts.map +1 -1
- package/lib/types/components/Select.js +4 -2
- package/lib/types/components/SkillsPicker.d.ts +4 -1
- package/lib/types/components/SkillsPicker.d.ts.map +1 -1
- package/lib/types/components/SkillsPicker.js +2 -2
- package/lib/types/components/SubagentCard.d.ts +2 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +6 -1
- package/lib/types/components/SubagentDashboard.d.ts +4 -0
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +9 -1
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +5 -4
- package/lib/types/components/SuggestionCard.d.ts +63 -0
- package/lib/types/components/SuggestionCard.d.ts.map +1 -0
- package/lib/types/components/SuggestionCard.js +77 -0
- package/lib/types/components/ThemePicker.d.ts +4 -1
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +2 -2
- package/lib/types/components/ThinkingToggle.d.ts +4 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +2 -2
- package/lib/types/components/TimelineRail.d.ts +53 -0
- package/lib/types/components/TimelineRail.d.ts.map +1 -0
- package/lib/types/components/TimelineRail.js +190 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts +6 -1
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -1
- package/lib/types/components/WorkspaceFlowPicker.js +4 -2
- package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
- package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceMenuPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +4 -1
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -1
- package/lib/types/components/WorkspacePicker.js +2 -2
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +5 -1
- package/lib/types/components/design-system/ListItem.d.ts +8 -1
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +8 -3
- package/lib/types/components/messages/AssistantTextMessage.d.ts +5 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +6 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +10 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +8 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +4 -2
- package/lib/types/components/messages/UserPromptMessage.d.ts +2 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +34 -2
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +13 -2
- package/lib/types/components/sessions/SessionListRow.d.ts +4 -1
- package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
- package/lib/types/components/sessions/SessionListRow.js +4 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +7 -1
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -1
- package/lib/types/components/trajectory/HotspotView.js +8 -2
- package/lib/types/components/trajectory/Ledger.d.ts +9 -1
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -1
- package/lib/types/components/trajectory/Ledger.js +23 -5
- package/lib/types/components/trajectory/WaveBand.d.ts +10 -1
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -1
- package/lib/types/components/trajectory/WaveBand.js +7 -2
- package/lib/types/dsh-adapter/channel.d.ts +16 -5
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +332 -29
- package/lib/types/dsh-adapter/index.d.ts +10 -2
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +4 -1
- package/lib/types/dsh-adapter/plugin.d.ts +0 -9
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +136 -6
- package/lib/types/i18n.d.ts +176 -15
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +51 -8
- package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -1
- package/lib/types/ink/components/AlternateScreen.js +13 -1
- package/lib/types/ink/components/App.d.ts +12 -1
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +101 -4
- package/lib/types/ink/components/ClockContext.d.ts.map +1 -1
- package/lib/types/ink/components/ClockContext.js +2 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +170 -91
- package/lib/types/ink/constants.d.ts +9 -0
- package/lib/types/ink/constants.d.ts.map +1 -1
- package/lib/types/ink/constants.js +9 -0
- package/lib/types/ink/events/click-event.d.ts +7 -16
- package/lib/types/ink/events/click-event.d.ts.map +1 -1
- package/lib/types/ink/events/click-event.js +16 -19
- package/lib/types/ink/events/event-handlers.d.ts +11 -1
- package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
- package/lib/types/ink/events/event-handlers.js +2 -0
- package/lib/types/ink/events/input-event.d.ts +9 -0
- package/lib/types/ink/events/input-event.d.ts.map +1 -1
- package/lib/types/ink/events/input-event.js +4 -0
- package/lib/types/ink/events/pointer-event.d.ts +61 -0
- package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
- package/lib/types/ink/events/pointer-event.js +61 -0
- package/lib/types/ink/events/wheel-event.d.ts +17 -0
- package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
- package/lib/types/ink/events/wheel-event.js +20 -0
- package/lib/types/ink/geometry-trace.d.ts +51 -0
- package/lib/types/ink/geometry-trace.d.ts.map +1 -0
- package/lib/types/ink/geometry-trace.js +83 -0
- package/lib/types/ink/hit-test.d.ts +56 -1
- package/lib/types/ink/hit-test.d.ts.map +1 -1
- package/lib/types/ink/hit-test.js +146 -8
- package/lib/types/ink/ink.d.ts +58 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +230 -29
- package/lib/types/ink/node-cache.d.ts +5 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.d.ts +8 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +101 -12
- package/lib/types/ink/render-node-to-output.d.ts +10 -0
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +111 -18
- package/lib/types/ink/timeline-rail.d.ts +138 -0
- package/lib/types/ink/timeline-rail.d.ts.map +1 -0
- package/lib/types/ink/timeline-rail.js +179 -0
- package/lib/types/ink/wrap-text.d.ts.map +1 -1
- package/lib/types/ink/wrap-text.js +47 -5
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +819 -337
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +56 -29
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +64 -22
- package/lib/types/screens/StatusLine.d.ts +2 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +17 -1
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
- package/lib/types/screens/TrajectoryScene.js +81 -14
- package/lib/types/screens/chatOverlay.d.ts +221 -0
- package/lib/types/screens/chatOverlay.d.ts.map +1 -0
- package/lib/types/screens/chatOverlay.js +114 -0
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +42 -6
- package/lib/types/tuiDisplayPrefs.d.ts +15 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +9 -0
- package/lib/types/utils/debug.d.ts +10 -0
- package/lib/types/utils/debug.d.ts.map +1 -1
- package/lib/types/utils/debug.js +24 -0
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat screen's transient-dialog layer (the pickers, dialogs and panels
|
|
3
|
+
* that float above the prompt in `<OverlayAbove>`, plus /tips) as one
|
|
4
|
+
* explicit state machine.
|
|
5
|
+
*
|
|
6
|
+
* Previously this layer lived in ~28 sibling `useState` booleans+indices in
|
|
7
|
+
* Chat.tsx, with mutual exclusion emerging from "an open picker makes the
|
|
8
|
+
* prompt inert, so no second open command can be typed", and with two
|
|
9
|
+
* hand-maintained OR-aggregates (`promptSelectionActive`,
|
|
10
|
+
* `dialogOverlayOpen`) whose comments warned they must stay exactly in sync
|
|
11
|
+
* with the per-panel render conditions. A single discriminated union makes
|
|
12
|
+
* the exclusion structural — one variable can only hold one variant — and
|
|
13
|
+
* turns both aggregates into derivations that cannot drift.
|
|
14
|
+
*
|
|
15
|
+
* Design constraints, in order:
|
|
16
|
+
* 1. Behavior-preserving: every keyboard path, open/close side effect and
|
|
17
|
+
* async-callback landing keeps its observable behavior. The one
|
|
18
|
+
* deliberate change: an async OPEN landing while another overlay is up
|
|
19
|
+
* (e.g. `/effort`'s listEfforts resolving after the user opened
|
|
20
|
+
* `/model`) now REPLACES it instead of stacking two panels — the
|
|
21
|
+
* stacked rendering was an unreachable-by-keyboard race, not a feature.
|
|
22
|
+
* 2. Pure and total: the reducer is a plain function, unit-tested by
|
|
23
|
+
* scripts/verify-chat-overlay.ts without a renderer. Actions that no
|
|
24
|
+
* longer apply (an async result landing after the overlay changed) are
|
|
25
|
+
* ignored rather than writing orphan state.
|
|
26
|
+
* 3. Async data caches (model list, preset roster, …) stay OUTSIDE the
|
|
27
|
+
* union in Chat.tsx: they persist across open/close so a reopened
|
|
28
|
+
* picker can paint the previous list while the fresh one loads,
|
|
29
|
+
* exactly as before.
|
|
30
|
+
*/
|
|
31
|
+
import type { ChatRow } from '../dsh-adapter/channel.js';
|
|
32
|
+
import type { TuiRewindMode } from '../dsh-adapter/extension-events.js';
|
|
33
|
+
import type { TuiWorkspaceCommandResult } from '../workspaces.js';
|
|
34
|
+
/** The `kind: 'choices'` result a workspace command can return. */
|
|
35
|
+
export type WorkspaceFlowChoices = Extract<TuiWorkspaceCommandResult, {
|
|
36
|
+
kind: 'choices';
|
|
37
|
+
}>;
|
|
38
|
+
/** Text-entry sub-state of the workspace flow (Tab into a choice's input). */
|
|
39
|
+
export type WorkspaceFlowInput = {
|
|
40
|
+
choiceId: string;
|
|
41
|
+
value: string;
|
|
42
|
+
cursor: number;
|
|
43
|
+
placeholder?: string;
|
|
44
|
+
};
|
|
45
|
+
export type ChatOverlay = {
|
|
46
|
+
kind: 'none';
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'thinking';
|
|
49
|
+
focus: number;
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'workspace-picker';
|
|
52
|
+
index: number;
|
|
53
|
+
} | {
|
|
54
|
+
kind: 'workspace-menu';
|
|
55
|
+
index: number;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'workspace-flow';
|
|
58
|
+
flow: WorkspaceFlowChoices;
|
|
59
|
+
index: number;
|
|
60
|
+
busy: boolean;
|
|
61
|
+
input: WorkspaceFlowInput | null;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'model';
|
|
64
|
+
index: number;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'skills';
|
|
67
|
+
index: number;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'activity';
|
|
70
|
+
index: number;
|
|
71
|
+
} | {
|
|
72
|
+
kind: 'effort';
|
|
73
|
+
index: number;
|
|
74
|
+
} | {
|
|
75
|
+
kind: 'preset';
|
|
76
|
+
index: number;
|
|
77
|
+
} | {
|
|
78
|
+
kind: 'theme';
|
|
79
|
+
index: number;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'permission';
|
|
82
|
+
index: number;
|
|
83
|
+
} | {
|
|
84
|
+
kind: 'plan';
|
|
85
|
+
index: number;
|
|
86
|
+
} | {
|
|
87
|
+
kind: 'lang';
|
|
88
|
+
index: number;
|
|
89
|
+
} | {
|
|
90
|
+
kind: 'history';
|
|
91
|
+
query: string;
|
|
92
|
+
cursor: number;
|
|
93
|
+
focus: number;
|
|
94
|
+
} | {
|
|
95
|
+
kind: 'rewind';
|
|
96
|
+
index: number;
|
|
97
|
+
confirm: ChatRow | null;
|
|
98
|
+
modes: readonly TuiRewindMode[] | null;
|
|
99
|
+
modeIndex: number;
|
|
100
|
+
busy: boolean;
|
|
101
|
+
} | {
|
|
102
|
+
kind: 'search';
|
|
103
|
+
} | {
|
|
104
|
+
kind: 'tips';
|
|
105
|
+
};
|
|
106
|
+
export declare const NO_OVERLAY: ChatOverlay;
|
|
107
|
+
export type ChatOverlayAction =
|
|
108
|
+
/** Open a variant, replacing whatever is up (including `none`). */
|
|
109
|
+
{
|
|
110
|
+
type: 'open';
|
|
111
|
+
overlay: ChatOverlay;
|
|
112
|
+
}
|
|
113
|
+
/** Close unconditionally (only dispatched from the open overlay's own keys). */
|
|
114
|
+
| {
|
|
115
|
+
type: 'close';
|
|
116
|
+
}
|
|
117
|
+
/** Close only if the given kind is still up — the safe form for async
|
|
118
|
+
* callbacks (a loader failing after the user already moved on). */
|
|
119
|
+
| {
|
|
120
|
+
type: 'close-if';
|
|
121
|
+
kind: ChatOverlay['kind'];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Open only while the current kind is one of `when` — the safe form for an
|
|
125
|
+
* OPEN that arrives from an async callback (`/effort`'s level list, the
|
|
126
|
+
* workspace target list, a workspace command's choices). A user who opened
|
|
127
|
+
* something else during the round trip keeps what they opened; the stale
|
|
128
|
+
* open is dropped. Synchronous opens keep using plain `open`.
|
|
129
|
+
*/
|
|
130
|
+
| {
|
|
131
|
+
type: 'open-if';
|
|
132
|
+
overlay: ChatOverlay;
|
|
133
|
+
when: readonly ChatOverlay['kind'][];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Move the focused row by one with wrap-around, over a list of `count`
|
|
137
|
+
* entries. On `rewind` this targets whichever cursor the sub-state focuses
|
|
138
|
+
* (mode list when a plugin offered modes, else the candidate list). A
|
|
139
|
+
* `count <= 0` move is a no-op (an empty list has no focus to move).
|
|
140
|
+
*/
|
|
141
|
+
| {
|
|
142
|
+
type: 'move';
|
|
143
|
+
delta: 1 | -1;
|
|
144
|
+
count: number;
|
|
145
|
+
}
|
|
146
|
+
/** Set the focused row to an absolute index — an async loader landing
|
|
147
|
+
* with the authoritative focus (model list / preset roster), or a mouse
|
|
148
|
+
* click on a row of a panel that stays open (effort slider, workspace
|
|
149
|
+
* flow). Ignored unless that panel is still up. */
|
|
150
|
+
| {
|
|
151
|
+
type: 'set-index';
|
|
152
|
+
kind: 'model' | 'preset' | 'effort' | 'workspace-flow' | 'rewind';
|
|
153
|
+
index: number;
|
|
154
|
+
}
|
|
155
|
+
/** Edit the history-search draft (query text, caret, focused match). */
|
|
156
|
+
| {
|
|
157
|
+
type: 'history-edit';
|
|
158
|
+
query?: string;
|
|
159
|
+
cursor?: number;
|
|
160
|
+
focus?: number;
|
|
161
|
+
}
|
|
162
|
+
/** Workspace flow: an action is running (keys except Esc are swallowed). */
|
|
163
|
+
| {
|
|
164
|
+
type: 'flow-busy';
|
|
165
|
+
busy: boolean;
|
|
166
|
+
}
|
|
167
|
+
/** Workspace flow: enter (object) or leave (null) the text-input state. */
|
|
168
|
+
| {
|
|
169
|
+
type: 'flow-input';
|
|
170
|
+
input: WorkspaceFlowInput | null;
|
|
171
|
+
}
|
|
172
|
+
/** Workspace flow: edit the text-input draft in place. */
|
|
173
|
+
| {
|
|
174
|
+
type: 'flow-input-edit';
|
|
175
|
+
value: string;
|
|
176
|
+
cursor: number;
|
|
177
|
+
}
|
|
178
|
+
/** Rewind: the plugin decision round-trip started / was abandoned. */
|
|
179
|
+
| {
|
|
180
|
+
type: 'rewind-busy';
|
|
181
|
+
busy: boolean;
|
|
182
|
+
}
|
|
183
|
+
/** Rewind: the plugin decision landed — show the confirm pane (modes turn
|
|
184
|
+
* it into a choice list). Stale decisions are dropped by the caller's
|
|
185
|
+
* request token before dispatch; a changed overlay drops them here. */
|
|
186
|
+
| {
|
|
187
|
+
type: 'rewind-decision';
|
|
188
|
+
confirm: ChatRow;
|
|
189
|
+
modes: readonly TuiRewindMode[] | null;
|
|
190
|
+
}
|
|
191
|
+
/** Rewind: Esc from the confirm/modes pane back to the candidate list. */
|
|
192
|
+
| {
|
|
193
|
+
type: 'rewind-back';
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* One-step wrap-around cursor move — the single source of the wrapping rule
|
|
197
|
+
* every list overlay uses (Chat.tsx's effort slider reads it too, to apply
|
|
198
|
+
* the newly focused level in the same keystroke that dispatches the move).
|
|
199
|
+
*/
|
|
200
|
+
export declare function wrapIndex(index: number, delta: 1 | -1, count: number): number;
|
|
201
|
+
export declare function chatOverlayReducer(state: ChatOverlay, action: ChatOverlayAction): ChatOverlay;
|
|
202
|
+
/**
|
|
203
|
+
* Whether the `<OverlayAbove>` wrapper mounts. Mounting is all-or-nothing:
|
|
204
|
+
* the renderer's removed-absolute-node blit detection only fires when the
|
|
205
|
+
* removed subtree itself is `position: absolute` (dom.ts
|
|
206
|
+
* collectRemovedRects), so the whole overlay must leave the tree when its
|
|
207
|
+
* last panel closes — see the mount-site comment in Chat.tsx.
|
|
208
|
+
*
|
|
209
|
+
* The per-kind data gates mirror the per-panel render conditions verbatim:
|
|
210
|
+
* a picker whose async list has not landed (or came back trivially small)
|
|
211
|
+
* paints nothing, so the wrapper must not mount for it either. `tips`
|
|
212
|
+
* returns true even though the panel renders in the prompt slot rather than
|
|
213
|
+
* inside the overlay — preserved verbatim from the boolean-era aggregate
|
|
214
|
+
* (the empty absolute wrapper is zero-size and paints nothing).
|
|
215
|
+
*/
|
|
216
|
+
export declare function dialogOverlayVisible(overlay: ChatOverlay, gates: {
|
|
217
|
+
workspaceTargetCount: number;
|
|
218
|
+
effortOptionCount: number;
|
|
219
|
+
presetOptionCount: number;
|
|
220
|
+
}): boolean;
|
|
221
|
+
//# sourceMappingURL=chatOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatOverlay.d.ts","sourceRoot":"","sources":["../../../src/screens/chatOverlay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export const NO_OVERLAY = { kind: 'none' };
|
|
2
|
+
/**
|
|
3
|
+
* One-step wrap-around cursor move — the single source of the wrapping rule
|
|
4
|
+
* every list overlay uses (Chat.tsx's effort slider reads it too, to apply
|
|
5
|
+
* the newly focused level in the same keystroke that dispatches the move).
|
|
6
|
+
*/
|
|
7
|
+
export function wrapIndex(index, delta, count) {
|
|
8
|
+
return delta === -1
|
|
9
|
+
? (index <= 0 ? count - 1 : index - 1)
|
|
10
|
+
: (index >= count - 1 ? 0 : index + 1);
|
|
11
|
+
}
|
|
12
|
+
export function chatOverlayReducer(state, action) {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case 'open':
|
|
15
|
+
return action.overlay;
|
|
16
|
+
case 'close':
|
|
17
|
+
return NO_OVERLAY;
|
|
18
|
+
case 'close-if':
|
|
19
|
+
return state.kind === action.kind ? NO_OVERLAY : state;
|
|
20
|
+
case 'open-if':
|
|
21
|
+
return action.when.includes(state.kind) ? action.overlay : state;
|
|
22
|
+
case 'move': {
|
|
23
|
+
if (action.count <= 0)
|
|
24
|
+
return state;
|
|
25
|
+
if (state.kind === 'rewind') {
|
|
26
|
+
// The confirm pane with plugin modes has its own cursor; the plain
|
|
27
|
+
// confirm pane has none (Enter/Esc only — a move must not disturb
|
|
28
|
+
// the list index behind it).
|
|
29
|
+
if (state.confirm !== null) {
|
|
30
|
+
return state.modes !== null
|
|
31
|
+
? { ...state, modeIndex: wrapIndex(state.modeIndex, action.delta, action.count) }
|
|
32
|
+
: state;
|
|
33
|
+
}
|
|
34
|
+
return { ...state, index: wrapIndex(state.index, action.delta, action.count) };
|
|
35
|
+
}
|
|
36
|
+
if (state.kind === 'thinking') {
|
|
37
|
+
return { ...state, focus: wrapIndex(state.focus, action.delta, action.count) };
|
|
38
|
+
}
|
|
39
|
+
if (state.kind === 'workspace-picker'
|
|
40
|
+
|| state.kind === 'workspace-menu'
|
|
41
|
+
|| state.kind === 'workspace-flow'
|
|
42
|
+
|| state.kind === 'model'
|
|
43
|
+
|| state.kind === 'skills'
|
|
44
|
+
|| state.kind === 'activity'
|
|
45
|
+
|| state.kind === 'effort'
|
|
46
|
+
|| state.kind === 'preset'
|
|
47
|
+
|| state.kind === 'theme'
|
|
48
|
+
|| state.kind === 'permission'
|
|
49
|
+
|| state.kind === 'plan'
|
|
50
|
+
|| state.kind === 'lang') {
|
|
51
|
+
return { ...state, index: wrapIndex(state.index, action.delta, action.count) };
|
|
52
|
+
}
|
|
53
|
+
if (state.kind === 'history') {
|
|
54
|
+
return { ...state, focus: wrapIndex(state.focus, action.delta, action.count) };
|
|
55
|
+
}
|
|
56
|
+
return state;
|
|
57
|
+
}
|
|
58
|
+
case 'set-index':
|
|
59
|
+
return state.kind === action.kind ? { ...state, index: action.index } : state;
|
|
60
|
+
case 'history-edit':
|
|
61
|
+
return state.kind === 'history'
|
|
62
|
+
? {
|
|
63
|
+
...state,
|
|
64
|
+
...(action.query === undefined ? {} : { query: action.query }),
|
|
65
|
+
...(action.cursor === undefined ? {} : { cursor: action.cursor }),
|
|
66
|
+
...(action.focus === undefined ? {} : { focus: action.focus }),
|
|
67
|
+
}
|
|
68
|
+
: state;
|
|
69
|
+
case 'flow-busy':
|
|
70
|
+
return state.kind === 'workspace-flow' ? { ...state, busy: action.busy } : state;
|
|
71
|
+
case 'flow-input':
|
|
72
|
+
return state.kind === 'workspace-flow' ? { ...state, input: action.input } : state;
|
|
73
|
+
case 'flow-input-edit':
|
|
74
|
+
return state.kind === 'workspace-flow' && state.input !== null
|
|
75
|
+
? { ...state, input: { ...state.input, value: action.value, cursor: action.cursor } }
|
|
76
|
+
: state;
|
|
77
|
+
case 'rewind-busy':
|
|
78
|
+
return state.kind === 'rewind' ? { ...state, busy: action.busy } : state;
|
|
79
|
+
case 'rewind-decision':
|
|
80
|
+
return state.kind === 'rewind'
|
|
81
|
+
? { ...state, busy: false, confirm: action.confirm, modes: action.modes, modeIndex: 0 }
|
|
82
|
+
: state;
|
|
83
|
+
case 'rewind-back':
|
|
84
|
+
return state.kind === 'rewind' ? { ...state, confirm: null, modes: null } : state;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Whether the `<OverlayAbove>` wrapper mounts. Mounting is all-or-nothing:
|
|
89
|
+
* the renderer's removed-absolute-node blit detection only fires when the
|
|
90
|
+
* removed subtree itself is `position: absolute` (dom.ts
|
|
91
|
+
* collectRemovedRects), so the whole overlay must leave the tree when its
|
|
92
|
+
* last panel closes — see the mount-site comment in Chat.tsx.
|
|
93
|
+
*
|
|
94
|
+
* The per-kind data gates mirror the per-panel render conditions verbatim:
|
|
95
|
+
* a picker whose async list has not landed (or came back trivially small)
|
|
96
|
+
* paints nothing, so the wrapper must not mount for it either. `tips`
|
|
97
|
+
* returns true even though the panel renders in the prompt slot rather than
|
|
98
|
+
* inside the overlay — preserved verbatim from the boolean-era aggregate
|
|
99
|
+
* (the empty absolute wrapper is zero-size and paints nothing).
|
|
100
|
+
*/
|
|
101
|
+
export function dialogOverlayVisible(overlay, gates) {
|
|
102
|
+
switch (overlay.kind) {
|
|
103
|
+
case 'none':
|
|
104
|
+
return false;
|
|
105
|
+
case 'workspace-picker':
|
|
106
|
+
return gates.workspaceTargetCount > 0;
|
|
107
|
+
case 'effort':
|
|
108
|
+
return gates.effortOptionCount > 1;
|
|
109
|
+
case 'preset':
|
|
110
|
+
return gates.presetOptionCount > 0;
|
|
111
|
+
default:
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
}
|
package/lib/types/tips.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../src/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;AAEhF,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,QAAQ,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAMzE,CAAA;AAED,eAAO,MAAM,IAAI,EAAE,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../src/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;AAEhF,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,QAAQ,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAMzE,CAAA;AAED,eAAO,MAAM,IAAI,EAAE,SAAS,GAAG,EA4lB9B,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,MAAM,MAAoB,GAAG,GAAG,CAErE;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,GAAG,EAAE,CAElD"}
|
package/lib/types/tips.js
CHANGED
|
@@ -146,8 +146,14 @@ export const TIPS = [
|
|
|
146
146
|
{
|
|
147
147
|
id: 'keys-mouse-click',
|
|
148
148
|
group: 'keys',
|
|
149
|
-
zh: '
|
|
150
|
-
en: 'Click
|
|
149
|
+
zh: '工具卡/thinking/摘要点击展开,子代理卡点击看详情;输入框点击定位光标',
|
|
150
|
+
en: 'Click tool/thinking/summary rows to fold; subagent cards open detail; click input to move caret',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: 'keys-mouse-scenes',
|
|
154
|
+
group: 'keys',
|
|
155
|
+
zh: '轨迹与 /settings 支持鼠标:行点击跳转/编辑,滚轮移动光标或焦点',
|
|
156
|
+
en: 'Trajectory and /settings take the mouse: row clicks jump/edit, the wheel moves cursor or focus',
|
|
151
157
|
},
|
|
152
158
|
// ── 命令 ──────────────────────────────────────────────────
|
|
153
159
|
{
|
|
@@ -327,8 +333,8 @@ export const TIPS = [
|
|
|
327
333
|
{
|
|
328
334
|
id: 'cmd-permission',
|
|
329
335
|
group: 'commands',
|
|
330
|
-
zh: '/permission
|
|
331
|
-
en: '/permission
|
|
336
|
+
zh: '/permission 弹出权限预设选择器(只读/工作区读写/完全访问)',
|
|
337
|
+
en: '/permission opens the permission-preset picker (read-only/workspace-write/full)',
|
|
332
338
|
},
|
|
333
339
|
{
|
|
334
340
|
id: 'cmd-plan-goal',
|
|
@@ -410,6 +416,36 @@ export const TIPS = [
|
|
|
410
416
|
zh: '底栏 TPS、轨迹条、上下文条默认关,/settings 里打开',
|
|
411
417
|
en: 'TPS, trajectory, context bars are off by default — enable in /settings',
|
|
412
418
|
},
|
|
419
|
+
{
|
|
420
|
+
id: 'disp-statusbar-session-id',
|
|
421
|
+
group: 'display',
|
|
422
|
+
zh: '底栏可显示短会话 ID(# 前 8 位),与日志文件名对应,/settings 里开',
|
|
423
|
+
en: 'Footer can show the short session id (# + 8 chars, matches the log filename) — enable in /settings',
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
id: 'disp-statusbar-title',
|
|
427
|
+
group: 'display',
|
|
428
|
+
zh: '底栏可显示会话标题;/rename 随时改',
|
|
429
|
+
en: 'Footer can show the session title; rename anytime with /rename',
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: 'disp-statusbar-fields',
|
|
433
|
+
group: 'display',
|
|
434
|
+
zh: '底栏字段逐项开关:token 总量、git 分支、模式、活动摘要…… /settings 里配',
|
|
435
|
+
en: 'Footer fields are per-field switches: token totals, git branch, mode, activity — set in /settings',
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'disp-statusbar-compact',
|
|
439
|
+
group: 'display',
|
|
440
|
+
zh: '底栏 compact 开=单行收纳;关=左右分组(指标在左、位置在右)',
|
|
441
|
+
en: 'Footer compact on = one merged line; off = metrics left, location right',
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: 'disp-statusbar-hint',
|
|
445
|
+
group: 'display',
|
|
446
|
+
zh: "空闲时 '? 查看快捷键' 常驻提示也是底栏开关(shortcutHint)",
|
|
447
|
+
en: 'The idle "? for shortcuts" reminder is itself a footer switch (shortcutHint)',
|
|
448
|
+
},
|
|
413
449
|
{
|
|
414
450
|
id: 'disp-context-warn',
|
|
415
451
|
group: 'display',
|
|
@@ -558,8 +594,8 @@ export const TIPS = [
|
|
|
558
594
|
{
|
|
559
595
|
id: 'pit-mouse-mode',
|
|
560
596
|
group: 'pitfalls',
|
|
561
|
-
zh: '
|
|
562
|
-
en: '
|
|
597
|
+
zh: '主界面鼠标需开 fullscreen;轨迹/resume 整屏页两种模式都带鼠标',
|
|
598
|
+
en: 'Main-chat mouse needs fullscreen; full-page screens (trajectory, /resume) have it in both modes',
|
|
563
599
|
},
|
|
564
600
|
{
|
|
565
601
|
id: 'pit-env-rename',
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
/** Background treatment applied to tool-call cards. */
|
|
2
2
|
export type ToolBackground = 'none' | 'subtle' | 'strong';
|
|
3
|
+
/**
|
|
4
|
+
* What the fullscreen transcript's right gutter shows:
|
|
5
|
+
* - `timeline`: Grok-style turn rail — one tick per user turn (conversation
|
|
6
|
+
* order, not scroll proportion), active turn highlighted, click to jump;
|
|
7
|
+
* - `scrollbar`: classic proportional thumb — position/size of the visible
|
|
8
|
+
* window over the whole content, click the track to scroll there;
|
|
9
|
+
* - `hidden`: no gutter; the transcript takes the full width.
|
|
10
|
+
*/
|
|
11
|
+
export type ScrollGutterMode = 'timeline' | 'scrollbar' | 'hidden';
|
|
3
12
|
/** Individually selectable fields in the status footer. */
|
|
4
13
|
export interface StatusBarConfig {
|
|
5
14
|
/** Prefer the compact, single-line presentation when space permits. */
|
|
@@ -22,6 +31,10 @@ export interface StatusBarConfig {
|
|
|
22
31
|
gitBranch: boolean;
|
|
23
32
|
/** Current session title. */
|
|
24
33
|
sessionTitle: boolean;
|
|
34
|
+
/** Short session id (# + first 8 chars), matching the session log filename. */
|
|
35
|
+
sessionId: boolean;
|
|
36
|
+
/** Compact goal chip (phase glyph + rounds) while a goal exists. */
|
|
37
|
+
goal: boolean;
|
|
25
38
|
/** Non-default session mode. */
|
|
26
39
|
mode: boolean;
|
|
27
40
|
/** Segmented context progress bar on its own footer row. */
|
|
@@ -37,6 +50,8 @@ export interface StatusBarConfig {
|
|
|
37
50
|
export declare const DEFAULT_STATUS_BAR: Readonly<StatusBarConfig>;
|
|
38
51
|
/** Normalize untrusted/config-layer values without mutating the input. */
|
|
39
52
|
export declare function normalizeToolBackground(value: unknown): ToolBackground;
|
|
53
|
+
/** Same normalize contract as toolBackground; `timeline` is the default. */
|
|
54
|
+
export declare function normalizeScrollGutter(value: unknown): ScrollGutterMode;
|
|
40
55
|
/** Merge a partial settings value over the stable status-bar defaults. */
|
|
41
56
|
export declare function normalizeStatusBar(value: unknown): StatusBarConfig;
|
|
42
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuiDisplayPrefs.d.ts","sourceRoot":"","sources":["../../src/tuiDisplayPrefs.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEzD,2DAA2D;AAC3D,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,qBAAqB;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAA;IACjB,iCAAiC;IACjC,GAAG,EAAE,OAAO,CAAA;IACZ,0CAA0C;IAC1C,YAAY,EAAE,OAAO,CAAA;IACrB,6BAA6B;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAA;IACf,oCAAoC;IACpC,GAAG,EAAE,OAAO,CAAA;IACZ,0BAA0B;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,6BAA6B;IAC7B,YAAY,EAAE,OAAO,CAAA;IACrB,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAA;IACnB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAA;IACjB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAA;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAA;CACtB;AAED,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"tuiDisplayPrefs.d.ts","sourceRoot":"","sources":["../../src/tuiDisplayPrefs.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEzD;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAA;AAElE,2DAA2D;AAC3D,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,qBAAqB;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAA;IACjB,iCAAiC;IACjC,GAAG,EAAE,OAAO,CAAA;IACZ,0CAA0C;IAC1C,YAAY,EAAE,OAAO,CAAA;IACrB,6BAA6B;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAA;IACf,oCAAoC;IACpC,GAAG,EAAE,OAAO,CAAA;IACZ,0BAA0B;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,6BAA6B;IAC7B,YAAY,EAAE,OAAO,CAAA;IACrB,+EAA+E;IAC/E,SAAS,EAAE,OAAO,CAAA;IAClB,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAA;IACb,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAA;IACnB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAA;IACjB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAA;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAA;CACtB;AAED,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,eAAe,CAkBvD,CAAA;AAMF,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAItE;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAItE;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CASlE;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,UAAO,GACb,MAAM,GAAG,SAAS,CASpB"}
|
|
@@ -10,6 +10,8 @@ export const DEFAULT_STATUS_BAR = Object.freeze({
|
|
|
10
10
|
tps: false,
|
|
11
11
|
gitBranch: false,
|
|
12
12
|
sessionTitle: false,
|
|
13
|
+
sessionId: false,
|
|
14
|
+
goal: true,
|
|
13
15
|
mode: false,
|
|
14
16
|
contextBar: false,
|
|
15
17
|
activity: false,
|
|
@@ -17,6 +19,7 @@ export const DEFAULT_STATUS_BAR = Object.freeze({
|
|
|
17
19
|
shortcutHint: false,
|
|
18
20
|
});
|
|
19
21
|
const TOOL_BACKGROUNDS = new Set(['none', 'subtle', 'strong']);
|
|
22
|
+
const SCROLL_GUTTERS = new Set(['timeline', 'scrollbar', 'hidden']);
|
|
20
23
|
const STATUS_BAR_KEYS = Object.keys(DEFAULT_STATUS_BAR);
|
|
21
24
|
/** Normalize untrusted/config-layer values without mutating the input. */
|
|
22
25
|
export function normalizeToolBackground(value) {
|
|
@@ -24,6 +27,12 @@ export function normalizeToolBackground(value) {
|
|
|
24
27
|
? value
|
|
25
28
|
: 'none';
|
|
26
29
|
}
|
|
30
|
+
/** Same normalize contract as toolBackground; `timeline` is the default. */
|
|
31
|
+
export function normalizeScrollGutter(value) {
|
|
32
|
+
return typeof value === 'string' && SCROLL_GUTTERS.has(value)
|
|
33
|
+
? value
|
|
34
|
+
: 'timeline';
|
|
35
|
+
}
|
|
27
36
|
/** Merge a partial settings value over the stable status-bar defaults. */
|
|
28
37
|
export function normalizeStatusBar(value) {
|
|
29
38
|
const normalized = { ...DEFAULT_STATUS_BAR };
|
|
@@ -5,4 +5,14 @@
|
|
|
5
5
|
* @param fields - Optional JSON-serialized fields appended to the line.
|
|
6
6
|
*/
|
|
7
7
|
export declare function logForDebugging(message: string, fields?: Record<string, unknown>): void;
|
|
8
|
+
/**
|
|
9
|
+
* Mouse-chain diagnostics: appends to `~/.dsh-cc/mouse-debug.log` when
|
|
10
|
+
* `DSH_TUI_DEBUG_MOUSE` is set. Unlike logForDebugging (stderr), a file
|
|
11
|
+
* keeps the fullscreen alt screen unpolluted and survives the session for
|
|
12
|
+
* post-mortem reading. Every append is try/catch-guarded — diagnostics
|
|
13
|
+
* must never take the UI down.
|
|
14
|
+
* @param message - Stage name (e.g. 'mouse arrive', 'dispatchClick').
|
|
15
|
+
* @param fields - Optional JSON-serialized fields appended to the line.
|
|
16
|
+
*/
|
|
17
|
+
export declare function logMouseDebug(message: string, fields?: Record<string, unknown>): void;
|
|
8
18
|
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/utils/debug.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/utils/debug.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAIvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASrF"}
|
package/lib/types/utils/debug.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { appendFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
1
4
|
/**
|
|
2
5
|
* Debug logger for the ported Ink core. Writes to stderr only when
|
|
3
6
|
* `DSH_TUI_DEBUG` is set, so normal runs stay quiet.
|
|
@@ -10,3 +13,24 @@ export function logForDebugging(message, fields) {
|
|
|
10
13
|
const suffix = fields === undefined ? '' : ` ${JSON.stringify(fields)}`;
|
|
11
14
|
process.stderr.write(`[dsh-tui] ${message}${suffix}\n`);
|
|
12
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Mouse-chain diagnostics: appends to `~/.dsh-cc/mouse-debug.log` when
|
|
18
|
+
* `DSH_TUI_DEBUG_MOUSE` is set. Unlike logForDebugging (stderr), a file
|
|
19
|
+
* keeps the fullscreen alt screen unpolluted and survives the session for
|
|
20
|
+
* post-mortem reading. Every append is try/catch-guarded — diagnostics
|
|
21
|
+
* must never take the UI down.
|
|
22
|
+
* @param message - Stage name (e.g. 'mouse arrive', 'dispatchClick').
|
|
23
|
+
* @param fields - Optional JSON-serialized fields appended to the line.
|
|
24
|
+
*/
|
|
25
|
+
export function logMouseDebug(message, fields) {
|
|
26
|
+
if (!process.env.DSH_TUI_DEBUG_MOUSE)
|
|
27
|
+
return;
|
|
28
|
+
const suffix = fields === undefined ? '' : ` ${JSON.stringify(fields)}`;
|
|
29
|
+
try {
|
|
30
|
+
const line = `${new Date().toISOString()} ${message}${suffix}\n`;
|
|
31
|
+
appendFileSync(join(homedir(), '.dsh-cc', 'mouse-debug.log'), line);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// ignore — see doc comment
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,qEAAqE;AACrE,eAAO,MAAM,QAAQ,QAA8B,CAAA;AAEnD,wEAAwE;AACxE,eAAO,MAAM,eAAe,QAA6B,CAAA;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,MAAwB,EAChC,MAAM,GAAE,MAAiB,GACxB,OAAO,CAOT;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,qEAAqE;AACrE,eAAO,MAAM,QAAQ,QAA8B,CAAA;AAEnD,wEAAwE;AACxE,eAAO,MAAM,eAAe,QAA6B,CAAA;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,MAAwB,EAChC,MAAM,GAAE,MAAiB,GACxB,OAAO,CAOT;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxD,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAEV"}
|
package/lib/types/utils/paths.js
CHANGED
|
@@ -57,6 +57,7 @@ export const RENAMED_ENV = {
|
|
|
57
57
|
CC_TUI_COMPACT_RETAIN: 'DSH_TUI_COMPACT_RETAIN',
|
|
58
58
|
DSH_CC_UPDATED_FROM: 'DSH_TUI_UPDATED_FROM',
|
|
59
59
|
DSH_CC_RENDER_LOG: 'DSH_TUI_RENDER_LOG',
|
|
60
|
+
DSH_CC_GEOMETRY_TRACE: 'DSH_TUI_GEOMETRY_TRACE',
|
|
60
61
|
DSH_CC_SESSION_ROOT: 'DSH_TUI_SESSION_ROOT',
|
|
61
62
|
DSH_CC_WORKSPACE: 'DSH_TUI_WORKSPACE',
|
|
62
63
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-harness-tui/dsh-tui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Claude Code style interactive TUI front door for DeepSeek Harness agents, built on the ported Ink core.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"prompt:debug": "node scripts/read-prompt-debug.mjs",
|
|
94
94
|
"tui": "node --import tsx/esm scripts/run.ts",
|
|
95
95
|
"smoke": "node --import tsx/esm scripts/smoke.tsx",
|
|
96
|
-
"verify:build": "npm run verify:boundary && npm run verify:contract && npm run verify:herdr && npm run verify:manifest-deps && npm run verify:patch-surface && npm run verify:web-coexistence && npm run verify:plugin-spec && npm run verify:plugin-grants && npm run verify:plugin-storage && npm run verify:plugin-messages && npm run verify:plugin-ledger && npm run verify:plugin-commands && npm run verify:plugin-negotiation && npm run verify:plugin-lifecycle && npm run verify:packaged-presets && npm run verify:minimal-preset-tools && npm run verify:liangshen-bootstrap && npm run verify:wheel-selection",
|
|
96
|
+
"verify:build": "npm run verify:boundary && npm run verify:contract && npm run verify:herdr && npm run verify:manifest-deps && npm run verify:patch-surface && npm run verify:web-coexistence && npm run verify:plugin-spec && npm run verify:plugin-grants && npm run verify:plugin-storage && npm run verify:plugin-messages && npm run verify:plugin-ledger && npm run verify:plugin-commands && npm run verify:plugin-negotiation && npm run verify:plugin-lifecycle && npm run verify:packaged-presets && npm run verify:minimal-preset-tools && npm run verify:liangshen-bootstrap && npm run verify:wheel-selection && npm run verify:pointer-events && npm run verify:chat-overlay",
|
|
97
97
|
"verify:boundary": "node --import tsx/esm scripts/verify-adapter-boundary.ts",
|
|
98
98
|
"verify:contract": "node --import tsx/esm scripts/verify-upstream-contract.ts",
|
|
99
99
|
"verify:herdr": "node --import tsx/esm scripts/verify-herdr-integration.ts",
|
|
@@ -119,6 +119,8 @@
|
|
|
119
119
|
"verify:tips": "node --import tsx/esm scripts/verify-tips.tsx",
|
|
120
120
|
"verify:thinking-preview": "node --import tsx/esm scripts/verify-thinking-preview.tsx",
|
|
121
121
|
"verify:wheel-selection": "node --import tsx/esm scripts/verify-wheel-selection.ts",
|
|
122
|
+
"verify:pointer-events": "node --import tsx/esm scripts/verify-pointer-events.ts",
|
|
123
|
+
"verify:chat-overlay": "node --import tsx/esm scripts/verify-chat-overlay.ts",
|
|
122
124
|
"sync:profile": "node scripts/sync-profile.mjs",
|
|
123
125
|
"sync:profile:check": "node scripts/sync-profile.mjs --check"
|
|
124
126
|
},
|