Merge remote-tracking branch 'origin/master' into worktree/skill-invocation-controls
# Conflicts: # docs/cordis-catalog/services.md # packages/host/apiproxy/README.i18n.yaml # packages/host/apiproxy/src/api-proxy.ts # packages/ui/tui/README.i18n.yaml
This commit is contained in:
@@ -71,6 +71,8 @@ export interface TuiHarnessOptions {
|
||||
load?(id: ReturnType<typeof SessionId>): Promise<{ meta: SessionHeader; events: Session['events'] }>
|
||||
}
|
||||
handoffResume?: TuiRuntime['handoffResume']
|
||||
/** Host-supplied exit line; absent exercises the no-message path. */
|
||||
goodbyeMessage?: TuiRuntime['goodbyeMessage']
|
||||
/** Set false to exercise the optional session-query degradation path. */
|
||||
mountSessionQuery?: boolean
|
||||
}
|
||||
@@ -253,6 +255,7 @@ export async function createTuiTestHarness<TerminalType extends Terminal, Exit e
|
||||
...(options.now === undefined ? {} : { now: options.now }),
|
||||
...(options.formatCwd === undefined ? {} : { formatCwd: options.formatCwd }),
|
||||
...(options.handoffResume === undefined ? {} : { handoffResume: options.handoffResume }),
|
||||
...(options.goodbyeMessage === undefined ? {} : { goodbyeMessage: options.goodbyeMessage }),
|
||||
gitBranch: options.gitBranch ?? (() => 'tui-staging'),
|
||||
})
|
||||
return { ctx, session, agent, terminal, exit, controller }
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=34 bufferRow=34
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,7 +17,7 @@ buffer
|
||||
6| "● Tool / bash / Run the coverage gate"
|
||||
style 0-36 fg=green
|
||||
7| "$ pnpm run test:coverage "
|
||||
style 0-23 fg=cyan
|
||||
style 0-23 dim
|
||||
8| "/workspace/project "
|
||||
style 0-17 dim
|
||||
9| "… +4 lines (Ctrl+O to expand) "
|
||||
@@ -39,11 +39,14 @@ buffer
|
||||
18| "● Tool / subagent"
|
||||
style 0-16 fg=green
|
||||
19| "Delegate renderer audit "
|
||||
style 0-99 dim
|
||||
20| "The renderer has explicit lifecycle ownership. "
|
||||
style 0-99 dim
|
||||
21| <blank>
|
||||
22| "● Tool / task_output"
|
||||
style 0-19 fg=green
|
||||
23| "Read output from background task subagent-7 "
|
||||
style 0-99 dim
|
||||
24| " "
|
||||
25| "… +2 lines (Ctrl+O to expand) "
|
||||
style 0-28 dim
|
||||
@@ -52,18 +55,20 @@ buffer
|
||||
28| "● Tool / skill"
|
||||
style 0-13 fg=green
|
||||
29| "Load skill dsh-code-review "
|
||||
style 0-99 dim
|
||||
30| "Loaded review instructions. "
|
||||
style 0-99 dim
|
||||
31| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
32| <blank>
|
||||
33| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
34| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
35-39| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=39 bufferRow=42
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,13 +17,17 @@ buffer
|
||||
6| "● Tool / bash / Run the coverage gate"
|
||||
style 0-36 fg=green
|
||||
7| "$ pnpm run test:coverage "
|
||||
style 0-23 fg=cyan
|
||||
style 0-23 dim
|
||||
8| "/workspace/project "
|
||||
style 0-17 dim
|
||||
9| "packages/ui/tui 100% "
|
||||
style 0-19 dim
|
||||
10| "4016 tests passed "
|
||||
style 0-16 dim
|
||||
11| "1 test skipped "
|
||||
style 0-13 dim
|
||||
12| "coverage complete "
|
||||
style 0-16 dim
|
||||
13| "[exit 0] "
|
||||
style 0-7 dim
|
||||
14| <blank>
|
||||
@@ -45,35 +49,42 @@ buffer
|
||||
23| "● Tool / subagent"
|
||||
style 0-16 fg=green
|
||||
24| "Delegate renderer audit "
|
||||
style 0-99 dim
|
||||
25| "The renderer has explicit lifecycle ownership. "
|
||||
style 0-99 dim
|
||||
26| <blank>
|
||||
27| "● Tool / task_output"
|
||||
style 0-19 fg=green
|
||||
28| "Read output from background task subagent-7 "
|
||||
style 0-99 dim
|
||||
29| " "
|
||||
30| "console "
|
||||
style 0-6 dim
|
||||
31| " started background task bash-5 "
|
||||
style 2-31 fg=cyan
|
||||
style 0-1 dim
|
||||
style 2-31 fg=cyan dim
|
||||
style 32-99 dim
|
||||
32| " "
|
||||
33| <blank>
|
||||
34| "● Tool / skill"
|
||||
style 0-13 fg=green
|
||||
35| "Load skill dsh-code-review "
|
||||
style 0-99 dim
|
||||
36| "Loaded review instructions. "
|
||||
style 0-99 dim
|
||||
37| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
38| <blank>
|
||||
39| "Tool cards expanded. "
|
||||
style 0-19 fg=bright-black
|
||||
39| "Tool and context cards expanded. "
|
||||
style 0-31 dim
|
||||
40| <blank>
|
||||
41| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
42| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -14,7 +14,7 @@ viewport
|
||||
style 8-8 fg=#2498ff bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -24,13 +24,13 @@ viewport
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
8| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
9-35| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=15 bufferRow=15
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -25,13 +25,13 @@ buffer
|
||||
style 0-14 dim
|
||||
13| <blank>
|
||||
14| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
15| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
16-35| <blank>
|
||||
|
||||
@@ -4,19 +4,19 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=18 bufferRow=18
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
style 0-8 dim italic
|
||||
6| "Inspecting width and styles. "
|
||||
style 0-27 fg=bright-black italic
|
||||
style 0-27 dim italic
|
||||
7| "Streaming visible state… "
|
||||
style 10-22 bold
|
||||
8| " "
|
||||
@@ -29,17 +29,16 @@ viewport
|
||||
style 0-30 dim
|
||||
13| <blank>
|
||||
14| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
15| "Show the live update. "
|
||||
16| <blank>
|
||||
17| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
18| " dsh ● press enter to steer and esc to cancel "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-44 dim
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-44 dim
|
||||
19-35| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=21 bufferRow=21
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -33,13 +33,13 @@ buffer
|
||||
style 0-14 dim
|
||||
19| <blank>
|
||||
20| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
21| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
22-35| <blank>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
terminal 92x32 buffer=normal length=38 base=6 viewport=6
|
||||
terminal 92x32 buffer=normal length=37 base=5 viewport=5
|
||||
lifecycle started=1 stopped=1 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor visible column=0 viewportRow=31 bufferRow=37
|
||||
cursor visible column=0 viewportRow=31 bufferRow=36
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,62 +17,60 @@ buffer
|
||||
style 0-46 dim
|
||||
6| <blank>
|
||||
7| "Keyboard shortcuts "
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 0-17 fg=bright-magenta bold
|
||||
8| "Enter send • Shift/Alt+Enter newline • Up/Down prompt history "
|
||||
style 0-60 fg=bright-black
|
||||
9| "Esc cancel active turn • Ctrl+O toggle tool cards • Ctrl+R toggle reasoning "
|
||||
style 0-74 fg=bright-black
|
||||
10| "Ctrl+C cancel while running; clear input or exit while idle • Ctrl+D exit "
|
||||
style 0-72 fg=bright-black
|
||||
11| " "
|
||||
12| "/clear — Clear the transcript view (session history is unchanged) "
|
||||
style 0-64 fg=bright-black
|
||||
13| "/exit — Exit after the active turn reaches idle "
|
||||
style 0-46 fg=bright-black
|
||||
14| "/help — Show keyboard shortcuts and commands "
|
||||
style 0-43 fg=bright-black
|
||||
15| "/model [[provider/]model] — Show or switch this session's model "
|
||||
style 0-62 fg=bright-black
|
||||
16| "/quit — Exit after the active turn reaches idle "
|
||||
style 0-46 fg=bright-black
|
||||
17| "/reasoning — Toggle reasoning blocks "
|
||||
style 0-35 fg=bright-black
|
||||
18| "/redraw — Invalidate components and redraw the terminal "
|
||||
style 0-54 fg=bright-black
|
||||
style 0-60 dim
|
||||
9| "Esc cancel turn • Ctrl+O cycle cards (collapse/expand/hide) • Ctrl+R toggle reasoning • "
|
||||
style 0-91 dim
|
||||
10| "Ctrl+L redraw "
|
||||
style 0-12 dim
|
||||
11| "Ctrl+C cancel while running; clear input or exit while idle • Ctrl+D exit "
|
||||
style 0-72 dim
|
||||
12| " "
|
||||
13| "/clear — Clear the transcript view (session history is unchanged) "
|
||||
style 0-64 dim
|
||||
14| "/exit — Exit after the active turn reaches idle "
|
||||
style 0-46 dim
|
||||
15| "/help — Show keyboard shortcuts and commands "
|
||||
style 0-43 dim
|
||||
16| "/model [[provider/]model] — Show or switch this session's model "
|
||||
style 0-62 dim
|
||||
17| "/palette — Show every color and attribute role this terminal renders "
|
||||
style 0-67 dim
|
||||
18| "/quit — Exit after the active turn reaches idle "
|
||||
style 0-46 dim
|
||||
19| "/reload — EXPERIMENTAL (dev): re-read loader config files and apply the diff (idle only) "
|
||||
style 0-87 fg=bright-black
|
||||
style 0-87 dim
|
||||
20| "/resume — List this workspace's resumable sessions "
|
||||
style 0-49 fg=bright-black
|
||||
style 0-49 dim
|
||||
21| "/status — Show session diagnostics, system prompt, and registered tools "
|
||||
style 0-70 fg=bright-black
|
||||
22| "/tools — Expand or collapse all tool cards "
|
||||
style 0-41 fg=bright-black
|
||||
23| "/skill:<name> [instructions] — load a skill into the conversation "
|
||||
style 0-64 fg=bright-black
|
||||
24| <blank>
|
||||
25| "provider stream failed after partial output "
|
||||
style 0-70 dim
|
||||
22| "/skill:<name> [instructions] — load a skill into the conversation "
|
||||
style 0-64 dim
|
||||
23| <blank>
|
||||
24| "provider stream failed after partial output "
|
||||
style 0-42 fg=red
|
||||
26| <blank>
|
||||
27| "The previous process ended during this turn. "
|
||||
25| <blank>
|
||||
26| "The previous process ended during this turn. "
|
||||
style 0-43 fg=yellow
|
||||
28| <blank>
|
||||
29| "Turn stopped: the agent was disposed. "
|
||||
27| <blank>
|
||||
28| "Turn stopped: the agent was disposed. "
|
||||
style 0-36 fg=yellow
|
||||
30| <blank>
|
||||
31| "Turn ended: plugin-policy. "
|
||||
29| <blank>
|
||||
30| "Turn ended: plugin-policy. "
|
||||
style 0-25 fg=yellow
|
||||
32| <blank>
|
||||
33| "Unknown command: /unknown-advanced-command "
|
||||
31| <blank>
|
||||
32| "Unknown command: /unknown-advanced-command "
|
||||
style 0-41 fg=yellow
|
||||
34| <blank>
|
||||
35| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
36| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
33| <blank>
|
||||
34| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
35| " dsh > "
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
37| <blank>
|
||||
36| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=17 bufferRow=17
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -28,13 +28,13 @@ buffer
|
||||
style 0-14 dim
|
||||
15| <blank>
|
||||
16| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
17| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
18-35| <blank>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
terminal 92x32 buffer=normal length=37 base=5 viewport=5
|
||||
terminal 92x32 buffer=normal length=36 base=4 viewport=4
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=31 bufferRow=36
|
||||
cursor hidden column=7 viewportRow=31 bufferRow=35
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,61 +17,59 @@ buffer
|
||||
style 0-46 dim
|
||||
6| <blank>
|
||||
7| "Keyboard shortcuts "
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 0-17 fg=bright-magenta bold
|
||||
8| "Enter send • Shift/Alt+Enter newline • Up/Down prompt history "
|
||||
style 0-60 fg=bright-black
|
||||
9| "Esc cancel active turn • Ctrl+O toggle tool cards • Ctrl+R toggle reasoning "
|
||||
style 0-74 fg=bright-black
|
||||
10| "Ctrl+C cancel while running; clear input or exit while idle • Ctrl+D exit "
|
||||
style 0-72 fg=bright-black
|
||||
11| " "
|
||||
12| "/clear — Clear the transcript view (session history is unchanged) "
|
||||
style 0-64 fg=bright-black
|
||||
13| "/exit — Exit after the active turn reaches idle "
|
||||
style 0-46 fg=bright-black
|
||||
14| "/help — Show keyboard shortcuts and commands "
|
||||
style 0-43 fg=bright-black
|
||||
15| "/model [[provider/]model] — Show or switch this session's model "
|
||||
style 0-62 fg=bright-black
|
||||
16| "/quit — Exit after the active turn reaches idle "
|
||||
style 0-46 fg=bright-black
|
||||
17| "/reasoning — Toggle reasoning blocks "
|
||||
style 0-35 fg=bright-black
|
||||
18| "/redraw — Invalidate components and redraw the terminal "
|
||||
style 0-54 fg=bright-black
|
||||
style 0-60 dim
|
||||
9| "Esc cancel turn • Ctrl+O cycle cards (collapse/expand/hide) • Ctrl+R toggle reasoning • "
|
||||
style 0-91 dim
|
||||
10| "Ctrl+L redraw "
|
||||
style 0-12 dim
|
||||
11| "Ctrl+C cancel while running; clear input or exit while idle • Ctrl+D exit "
|
||||
style 0-72 dim
|
||||
12| " "
|
||||
13| "/clear — Clear the transcript view (session history is unchanged) "
|
||||
style 0-64 dim
|
||||
14| "/exit — Exit after the active turn reaches idle "
|
||||
style 0-46 dim
|
||||
15| "/help — Show keyboard shortcuts and commands "
|
||||
style 0-43 dim
|
||||
16| "/model [[provider/]model] — Show or switch this session's model "
|
||||
style 0-62 dim
|
||||
17| "/palette — Show every color and attribute role this terminal renders "
|
||||
style 0-67 dim
|
||||
18| "/quit — Exit after the active turn reaches idle "
|
||||
style 0-46 dim
|
||||
19| "/reload — EXPERIMENTAL (dev): re-read loader config files and apply the diff (idle only) "
|
||||
style 0-87 fg=bright-black
|
||||
style 0-87 dim
|
||||
20| "/resume — List this workspace's resumable sessions "
|
||||
style 0-49 fg=bright-black
|
||||
style 0-49 dim
|
||||
21| "/status — Show session diagnostics, system prompt, and registered tools "
|
||||
style 0-70 fg=bright-black
|
||||
22| "/tools — Expand or collapse all tool cards "
|
||||
style 0-41 fg=bright-black
|
||||
23| "/skill:<name> [instructions] — load a skill into the conversation "
|
||||
style 0-64 fg=bright-black
|
||||
24| <blank>
|
||||
25| "provider stream failed after partial output "
|
||||
style 0-70 dim
|
||||
22| "/skill:<name> [instructions] — load a skill into the conversation "
|
||||
style 0-64 dim
|
||||
23| <blank>
|
||||
24| "provider stream failed after partial output "
|
||||
style 0-42 fg=red
|
||||
26| <blank>
|
||||
27| "The previous process ended during this turn. "
|
||||
25| <blank>
|
||||
26| "The previous process ended during this turn. "
|
||||
style 0-43 fg=yellow
|
||||
28| <blank>
|
||||
29| "Turn stopped: the agent was disposed. "
|
||||
27| <blank>
|
||||
28| "Turn stopped: the agent was disposed. "
|
||||
style 0-36 fg=yellow
|
||||
30| <blank>
|
||||
31| "Turn ended: plugin-policy. "
|
||||
29| <blank>
|
||||
30| "Turn ended: plugin-policy. "
|
||||
style 0-25 fg=yellow
|
||||
32| <blank>
|
||||
33| "Unknown command: /unknown-advanced-command "
|
||||
31| <blank>
|
||||
32| "Unknown command: /unknown-advanced-command "
|
||||
style 0-41 fg=yellow
|
||||
34| <blank>
|
||||
35| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
36| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
33| <blank>
|
||||
34| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
35| " dsh > "
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=11 viewportRow=8 bufferRow=8
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,15 +17,15 @@ viewport
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
8| " dsh > @tsc "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 11-11 inverse
|
||||
9| " → File · terminal-special-case.t src/terminal-special-case.ts "
|
||||
style 7-38 fg=bright-blue
|
||||
style 7-38 fg=bright-magenta
|
||||
10-35| <blank>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
terminal 92x32 buffer=normal length=32 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=15 viewportRow=13 bufferRow=13
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
8| " dsh > "
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
9-11| <blank>
|
||||
12| " ╭ Select model ────────────────────────────────────────────────────────────╮ "
|
||||
style 8-83 fg=bright-magenta
|
||||
13| " │ > pro │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 15-15 inverse
|
||||
style 83-83 fg=bright-magenta
|
||||
14| " │ │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 83-83 fg=bright-magenta
|
||||
15| " │ → deepseek/deepseek-v4-pro DeepSeek V4 Pro │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 10-58 fg=bright-magenta inverse
|
||||
style 83-83 fg=bright-magenta
|
||||
16| " │ │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 83-83 fg=bright-magenta
|
||||
17| " │ type to filter • ↑/↓ move • Shift+Tab reasoning • Enter select • Esc │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 10-77 dim
|
||||
style 83-83 fg=bright-magenta
|
||||
18| " ╰──────────────────────────────────────────────────────────────────────────╯ "
|
||||
style 8-83 fg=bright-magenta
|
||||
19-31| <blank>
|
||||
@@ -1,13 +1,13 @@
|
||||
terminal 92x32 buffer=normal length=32 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=0 viewportRow=31 bufferRow=31
|
||||
cursor hidden column=12 viewportRow=13 bufferRow=13
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,33 +17,40 @@ buffer
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
8| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
9-12| <blank>
|
||||
13| " ╭ Select model ────────────────────────────────────────────────────────────╮ "
|
||||
style 8-83 fg=bright-blue
|
||||
14| " │ → deepseek/deepseek-v4-flash DeepSeek V4 Flash — current │ "
|
||||
style 8-8 fg=bright-blue
|
||||
style 10-70 fg=bright-blue inverse
|
||||
style 83-83 fg=bright-blue
|
||||
15| " │ deepseek/deepseek-v4-pro DeepSeek V4 Pro │ "
|
||||
style 8-8 fg=bright-blue
|
||||
style 36-58 fg=bright-black
|
||||
style 83-83 fg=bright-blue
|
||||
16| " │ │ "
|
||||
style 8-8 fg=bright-blue
|
||||
style 83-83 fg=bright-blue
|
||||
17| " │ ↑/↓ navigate • Shift+Tab reasoning • Enter select • Esc cancel │ "
|
||||
style 8-8 fg=bright-blue
|
||||
style 10-71 dim
|
||||
style 83-83 fg=bright-blue
|
||||
18| " ╰──────────────────────────────────────────────────────────────────────────╯ "
|
||||
style 8-83 fg=bright-blue
|
||||
19-31| <blank>
|
||||
9-11| <blank>
|
||||
12| " ╭ Select model ────────────────────────────────────────────────────────────╮ "
|
||||
style 8-83 fg=bright-magenta
|
||||
13| " │ > │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 12-12 inverse
|
||||
style 83-83 fg=bright-magenta
|
||||
14| " │ │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 83-83 fg=bright-magenta
|
||||
15| " │ → deepseek/deepseek-v4-flash DeepSeek V4 Flash — current │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 10-70 fg=bright-magenta inverse
|
||||
style 83-83 fg=bright-magenta
|
||||
16| " │ deepseek/deepseek-v4-pro DeepSeek V4 Pro │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 36-58 dim
|
||||
style 83-83 fg=bright-magenta
|
||||
17| " │ │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 83-83 fg=bright-magenta
|
||||
18| " │ type to filter • ↑/↓ move • Shift+Tab reasoning • Enter select • Esc │ "
|
||||
style 8-8 fg=bright-magenta
|
||||
style 10-77 dim
|
||||
style 83-83 fg=bright-magenta
|
||||
19| " ╰──────────────────────────────────────────────────────────────────────────╯ "
|
||||
style 8-83 fg=bright-magenta
|
||||
20-31| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=10 bufferRow=10
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,16 +17,16 @@ buffer
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "Model selected: deepseek/deepseek-v4-pro. New steps will use it. "
|
||||
style 0-63 fg=bright-black
|
||||
style 0-63 dim
|
||||
8| <blank>
|
||||
9| "/workspace/project (tui-staging) deepseek-v4-pro ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-48 fg=bright-black
|
||||
style 51-55 fg=bright-black
|
||||
style 58-67 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-48 dim
|
||||
style 51-55 dim
|
||||
style 58-67 dim
|
||||
10| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
11-31| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=0 viewportRow=19 bufferRow=19
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,23 +17,23 @@ viewport
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 "
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-55 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-55 dim
|
||||
8| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
9-11| <blank>
|
||||
12| " "
|
||||
13| " Question 1/1 (1 unanswered) · Confirm "
|
||||
style 2-38 fg=bright-black
|
||||
style 2-38 dim
|
||||
14| " Continue with this change? "
|
||||
15| " "
|
||||
16| " › 1. Proceed Apply the proposed change "
|
||||
style 2-13 fg=bright-blue bold
|
||||
style 16-40 fg=bright-black
|
||||
style 2-13 fg=bright-magenta bold
|
||||
style 16-40 dim
|
||||
17| " Tab custom answer • Enter submit • Esc interrupt "
|
||||
style 2-49 dim
|
||||
18| " "
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=56 viewportRow=17 bufferRow=17
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -15,17 +15,17 @@ viewport
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| " "
|
||||
6| " Question 1/3 (3 unanswered) · Coverage "
|
||||
style 2-39 fg=bright-black
|
||||
style 2-39 dim
|
||||
7| " Which advanced TUI states belong in the required "
|
||||
8| " matrix? "
|
||||
9| " "
|
||||
10| " › 1. [ ] Code Mode run_code programs and capture "
|
||||
style 2-19 fg=bright-blue bold
|
||||
style 25-53 fg=bright-black
|
||||
style 2-19 fg=bright-magenta bold
|
||||
style 25-53 dim
|
||||
11| " 2. [ ] Workflows phases and parallel agents "
|
||||
style 25-50 fg=bright-black
|
||||
style 25-50 dim
|
||||
12| " 3. [ ] Cordis tools inspect, mount, and unmount "
|
||||
style 25-51 fg=bright-black
|
||||
style 25-51 dim
|
||||
13| " 1/4 "
|
||||
style 2-4 dim
|
||||
14| " Tab custom answer • ↑/↓ navigate • Space toggle • "
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=0 viewportRow=19 bufferRow=19
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -18,17 +18,17 @@ viewport
|
||||
6| <blank>
|
||||
7| " "
|
||||
8| " Question 1/3 (3 unanswered) · Coverage "
|
||||
style 2-39 fg=bright-black
|
||||
style 2-39 dim
|
||||
9| " Which advanced TUI states belong in the required "
|
||||
10| " matrix? "
|
||||
11| " "
|
||||
12| " › 1. [ ] Code Mode run_code programs and capture "
|
||||
style 2-19 fg=bright-blue bold
|
||||
style 25-53 fg=bright-black
|
||||
style 2-19 fg=bright-magenta bold
|
||||
style 25-53 dim
|
||||
13| " 2. [ ] Workflows phases and parallel agents "
|
||||
style 25-50 fg=bright-black
|
||||
style 25-50 dim
|
||||
14| " 3. [ ] Cordis tools inspect, mount, and unmount "
|
||||
style 25-51 fg=bright-black
|
||||
style 25-51 dim
|
||||
15| " 1/4 "
|
||||
style 2-4 dim
|
||||
16| " Tab custom answer • ↑/↓ navigate • Space toggle • "
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
terminal 92x32 buffer=normal length=32 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=6 viewportRow=4 bufferRow=4
|
||||
buffer
|
||||
0| " "
|
||||
1| " Resume session (1 of 3) "
|
||||
style 2-24 fg=bright-magenta bold
|
||||
2| " "
|
||||
3| " ╭──────────────────────────────────────────────────────────────────────────────────────╮ "
|
||||
style 2-89 dim
|
||||
4| " │ ⌕ │ "
|
||||
style 2-2 dim
|
||||
style 6-6 inverse
|
||||
style 89-89 dim
|
||||
5| " ╰──────────────────────────────────────────────────────────────────────────────────────╯ "
|
||||
style 2-89 dim
|
||||
6| " "
|
||||
7| " all workspaces (3) ⇥ this workspace (2) "
|
||||
style 2-19 fg=bright-magenta
|
||||
style 20-41 dim
|
||||
8| " "
|
||||
9| " ❯ Untitled session "
|
||||
style 2-19 fg=bright-magenta bold
|
||||
10| " 2026-07-23T08:00:00.000Z · no completed turn · route unavailable "
|
||||
style 2-67 dim
|
||||
11| " current · live · main-session "
|
||||
style 2-32 dim
|
||||
12| " workspace /workspace/project "
|
||||
style 2-31 dim
|
||||
13| " unavailable: current session "
|
||||
style 2-31 fg=yellow
|
||||
14| " Other workspace work "
|
||||
15| " 2024-02-02T00:00:08.000Z · turn 1: completed · deepseek/deepseek-v4-pro "
|
||||
style 2-74 dim
|
||||
16| " persisted · elsewhere-session "
|
||||
style 2-32 dim
|
||||
17| " workspace /workspace/other "
|
||||
style 2-29 dim
|
||||
18| " Resume selector design "
|
||||
19| " 2024-01-01T00:00:08.000Z · turn 1: completed · deepseek/deepseek-v4-pro "
|
||||
style 2-74 dim
|
||||
20| " persisted · earlier-session "
|
||||
style 2-30 dim
|
||||
21| " workspace /workspace/project "
|
||||
style 2-31 dim
|
||||
22| " "
|
||||
23| " "
|
||||
24| " "
|
||||
25| " "
|
||||
26| " "
|
||||
27| " "
|
||||
28| " "
|
||||
29| " "
|
||||
30| " Type to search • ↑/↓ navigate • Tab scope • Enter resume • Esc clear/cancel "
|
||||
style 2-84 dim
|
||||
31| " "
|
||||
@@ -5,7 +5,7 @@ cursor hidden column=6 viewportRow=4 bufferRow=4
|
||||
buffer
|
||||
0| " "
|
||||
1| " Resume session (1 of 2) "
|
||||
style 2-24 fg=bright-blue bold
|
||||
style 2-24 fg=bright-magenta bold
|
||||
2| " "
|
||||
3| " ╭──────────────────────────────────────────────────────────────────────────────────────╮ "
|
||||
style 2-89 dim
|
||||
@@ -16,20 +16,21 @@ buffer
|
||||
5| " ╰──────────────────────────────────────────────────────────────────────────────────────╯ "
|
||||
style 2-89 dim
|
||||
6| " "
|
||||
7| " /workspace/project "
|
||||
style 2-19 fg=bright-black
|
||||
7| " this workspace /workspace/project ⇥ all workspaces (3) "
|
||||
style 2-34 fg=bright-magenta
|
||||
style 35-56 dim
|
||||
8| " "
|
||||
9| " ❯ Untitled session "
|
||||
style 2-19 fg=bright-blue bold
|
||||
style 2-19 fg=bright-magenta bold
|
||||
10| " 2026-07-23T08:00:00.000Z · no completed turn · route unavailable "
|
||||
style 2-67 fg=bright-black
|
||||
style 2-67 dim
|
||||
11| " current · live · main-session "
|
||||
style 2-32 dim
|
||||
12| " unavailable: current session "
|
||||
style 2-31 fg=yellow
|
||||
13| " Resume selector design "
|
||||
14| " 2024-01-01T00:00:08.000Z · turn 1: completed · deepseek/deepseek-v4-pro "
|
||||
style 2-74 fg=bright-black
|
||||
style 2-74 dim
|
||||
15| " persisted · earlier-session "
|
||||
style 2-30 dim
|
||||
16| " "
|
||||
@@ -46,6 +47,6 @@ buffer
|
||||
27| " "
|
||||
28| " "
|
||||
29| " "
|
||||
30| " Type to search • ↑/↓ navigate • Enter resume • Esc clear/cancel "
|
||||
style 2-70 dim
|
||||
30| " Type to search • ↑/↓ navigate • Tab scope • Enter resume • Esc clear/cancel "
|
||||
style 2-84 dim
|
||||
31| " "
|
||||
|
||||
@@ -4,15 +4,15 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=12 bufferRow=12
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
5| "Start then cancel. "
|
||||
6| <blank>
|
||||
7| "Retrying model request (1/∞) in 1000ms: temporary transport failure "
|
||||
@@ -22,13 +22,13 @@ buffer
|
||||
style 0-14 fg=yellow
|
||||
10| <blank>
|
||||
11| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
12| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
13-35| <blank>
|
||||
|
||||
@@ -4,28 +4,28 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=10 bufferRow=10
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
5| "Let the bounded policy exhaust. "
|
||||
6| <blank>
|
||||
7| "provider still unavailable "
|
||||
style 0-25 fg=red
|
||||
8| <blank>
|
||||
9| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
10| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
11-35| <blank>
|
||||
|
||||
@@ -4,28 +4,28 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=10 bufferRow=10
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
5| "Recover this request. "
|
||||
6| <blank>
|
||||
7| "Retrying model request (1/2) in 500ms: provider rate limit "
|
||||
style 0-57 fg=yellow
|
||||
8| <blank>
|
||||
9| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
10| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
11-35| <blank>
|
||||
|
||||
@@ -4,28 +4,28 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=10 bufferRow=10
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
5| "Recover this request. "
|
||||
6| <blank>
|
||||
7| "Retrying model request (1/2) in 500ms: provider rate limit "
|
||||
style 0-57 fg=yellow
|
||||
8| <blank>
|
||||
9| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
10| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
11-35| <blank>
|
||||
|
||||
@@ -4,15 +4,15 @@ title "DSH session reference"
|
||||
cursor hidden column=7 viewportRow=14 bufferRow=14
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Session reference snapshot."
|
||||
style 1-27 fg=bright-black
|
||||
style 1-27 dim
|
||||
2| " target-session"
|
||||
style 1-14 dim
|
||||
3| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
5| "Use @Source session "
|
||||
6| <blank>
|
||||
7| "Referenced sessions · Source session (source-session) "
|
||||
@@ -25,11 +25,11 @@ buffer
|
||||
style 0-46 dim
|
||||
12| <blank>
|
||||
13| "/workspace/project mock ↑0 ↓0"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 20-23 fg=bright-black
|
||||
style 26-30 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 20-23 dim
|
||||
style 26-30 dim
|
||||
14| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
15-23| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=14 viewportRow=8 bufferRow=8
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,15 +17,15 @@ viewport
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
8| " dsh > @design "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 14-14 inverse
|
||||
9| " → Session · Searchable design re opaque-source-id · /workspace/project · 1970-01-01T0 "
|
||||
style 7-38 fg=bright-blue
|
||||
style 7-38 fg=bright-magenta
|
||||
10-35| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=38 viewportRow=13 bufferRow=13
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -17,9 +17,9 @@ viewport
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "/workspace/project (tui-staging) deepseek-v"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-43 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-43 dim
|
||||
8| " ↑ 1 more "
|
||||
style 1-14 dim
|
||||
9| " enough detail to wrap across multiple "
|
||||
|
||||
@@ -4,10 +4,10 @@ title "Inspect session diagnostics — DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=35 bufferRow=43
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Inspect session diagnostics"
|
||||
style 1-27 fg=bright-black
|
||||
style 1-27 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -18,28 +18,28 @@ buffer
|
||||
style 0-14 dim
|
||||
7| <blank>
|
||||
8| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
9| "inspect this session "
|
||||
10| <blank>
|
||||
11| "╭─ Session status ─────────────────────────────────────╮"
|
||||
style 0-2 dim
|
||||
style 3-16 fg=bright-blue bold
|
||||
style 3-16 fg=bright-magenta bold
|
||||
style 17-55 dim
|
||||
12| "│ Session: main-session │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
13| "│ Title: Inspect session diagnostics │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
14| "│ Directory: /workspace/project │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
15| "│ Model: deepseek/deepseek-v4-pro (effort │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 40-55 dim
|
||||
16| "│ default; reasoning blocks shown) │"
|
||||
style 0-0 dim
|
||||
@@ -50,7 +50,7 @@ buffer
|
||||
style 55-55 dim
|
||||
18| "│ Agent: idle · 7 events · 1 turn · 1 step · 1 │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
19| "│ tool call │"
|
||||
style 0-0 dim
|
||||
@@ -60,13 +60,13 @@ buffer
|
||||
style 55-55 dim
|
||||
21| "│ Tokens: 1,250 input + 340 output │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
22| "│ KV cache: [███████████░░░░░] 67% hit (3,000 read │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 15-15 dim
|
||||
style 16-26 fg=bright-blue
|
||||
style 16-26 fg=bright-magenta
|
||||
style 27-32 dim
|
||||
style 55-55 dim
|
||||
23| "│ + 250 write) │"
|
||||
@@ -74,9 +74,9 @@ buffer
|
||||
style 55-55 dim
|
||||
24| "│ Context: [█████░░░░░░░░░░░] 33% used (42,000 / │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 15-15 dim
|
||||
style 16-20 fg=bright-blue
|
||||
style 16-20 fg=bright-magenta
|
||||
style 21-32 dim
|
||||
style 55-55 dim
|
||||
25| "│ 128,000) │"
|
||||
@@ -87,17 +87,17 @@ buffer
|
||||
style 55-55 dim
|
||||
27| "│ Created: 2026-07-22 09:10:11 UTC │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
28| "│ Active: 2026-07-22 09:10:11 UTC │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 55-55 dim
|
||||
29| "╰──────────────────────────────────────────────────────╯"
|
||||
style 0-55 dim
|
||||
30| <blank>
|
||||
31| "System prompt "
|
||||
style 0-12 fg=bright-blue bold
|
||||
style 0-12 fg=bright-magenta bold
|
||||
32| "You are an AI agent powered by the DeepSeek Harness SDK."
|
||||
33| " "
|
||||
34| "Paths prefixed with @ are files explicitly referenced by"
|
||||
@@ -106,15 +106,15 @@ buffer
|
||||
37| "reading it. "
|
||||
38| <blank>
|
||||
39| "Registered tools "
|
||||
style 0-15 fg=bright-blue bold
|
||||
style 0-15 fg=bright-magenta bold
|
||||
40| "read, write "
|
||||
41| <blank>
|
||||
42| "/workspace/project (tui-staging) deepseek-v4-pro ↑1.3k"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-48 fg=bright-black
|
||||
style 51-55 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-48 dim
|
||||
style 51-55 dim
|
||||
43| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -4,10 +4,10 @@ title "Inspect session diagnostics — DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=31 bufferRow=37
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Inspect session diagnostics"
|
||||
style 1-27 fg=bright-black
|
||||
style 1-27 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -18,28 +18,28 @@ buffer
|
||||
style 0-14 dim
|
||||
7| <blank>
|
||||
8| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
9| "inspect this session "
|
||||
10| <blank>
|
||||
11| "╭─ Session status ───────────────────────────────────────────────────────────────╮"
|
||||
style 0-2 dim
|
||||
style 3-16 fg=bright-blue bold
|
||||
style 3-16 fg=bright-magenta bold
|
||||
style 17-81 dim
|
||||
12| "│ Session: main-session │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
13| "│ Title: Inspect session diagnostics │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
14| "│ Directory: /workspace/project │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
15| "│ Model: deepseek/deepseek-v4-pro (effort default; reasoning blocks shown) │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 40-79 dim
|
||||
style 81-81 dim
|
||||
16| "│ │"
|
||||
@@ -47,27 +47,27 @@ buffer
|
||||
style 81-81 dim
|
||||
17| "│ Agent: idle · 7 events · 1 turn · 1 step · 1 tool call │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
18| "│ │"
|
||||
style 0-0 dim
|
||||
style 81-81 dim
|
||||
19| "│ Tokens: 1,250 input + 340 output │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
20| "│ KV cache: [███████████░░░░░] 67% hit (3,000 read + 250 write) │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 15-15 dim
|
||||
style 16-26 fg=bright-blue
|
||||
style 16-26 fg=bright-magenta
|
||||
style 27-32 dim
|
||||
style 81-81 dim
|
||||
21| "│ Context: [█████░░░░░░░░░░░] 33% used (42,000 / 128,000) │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 15-15 dim
|
||||
style 16-20 fg=bright-blue
|
||||
style 16-20 fg=bright-magenta
|
||||
style 21-32 dim
|
||||
style 81-81 dim
|
||||
22| "│ │"
|
||||
@@ -75,33 +75,33 @@ buffer
|
||||
style 81-81 dim
|
||||
23| "│ Created: 2026-07-22 09:10:11 UTC │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
24| "│ Active: 2026-07-22 09:10:11 UTC │"
|
||||
style 0-0 dim
|
||||
style 3-12 fg=bright-black
|
||||
style 3-12 dim
|
||||
style 81-81 dim
|
||||
25| "╰────────────────────────────────────────────────────────────────────────────────╯"
|
||||
style 0-81 dim
|
||||
26| <blank>
|
||||
27| "System prompt "
|
||||
style 0-12 fg=bright-blue bold
|
||||
style 0-12 fg=bright-magenta bold
|
||||
28| "You are an AI agent powered by the DeepSeek Harness SDK. "
|
||||
29| " "
|
||||
30| "Paths prefixed with @ are files explicitly referenced by the user. Use the read tool when "
|
||||
31| "their contents are needed; do not claim to have inspected a file before reading it. "
|
||||
32| <blank>
|
||||
33| "Registered tools "
|
||||
style 0-15 fg=bright-blue bold
|
||||
style 0-15 fg=bright-magenta bold
|
||||
34| "read, write "
|
||||
35| <blank>
|
||||
36| "/workspace/project (tui-staging) deepseek-v4-pro ↑1.3k ↓340 cache 67% 33% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-48 fg=bright-black
|
||||
style 51-71 fg=bright-black
|
||||
style 74-84 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-48 dim
|
||||
style 51-71 dim
|
||||
style 74-84 dim
|
||||
37| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -4,31 +4,31 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=11 bufferRow=11
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
style 0-8 dim italic
|
||||
6| "Checking the result. "
|
||||
style 0-19 fg=bright-black italic
|
||||
style 0-19 dim italic
|
||||
7| "The result is ready. "
|
||||
8| "Model wait 1.0s · Thinking 2.0s · Response 3.0s · Completed 2026-07-21 14:32:12 "
|
||||
style 0-78 dim
|
||||
9| <blank>
|
||||
10| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
11| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
12-35| <blank>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
terminal 44x18 buffer=normal length=18 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=15 bufferRow=15
|
||||
cursor hidden column=7 viewportRow=14 bufferRow=14
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -16,21 +16,22 @@ buffer
|
||||
5| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "Context · workspace-context "
|
||||
7| "Context · workspace-context"
|
||||
style 0-26 dim
|
||||
8| "system-reminder "
|
||||
style 0-14 fg=bright-black
|
||||
9| " Additional instructions from: "
|
||||
10| "nested/AGENTS.md "
|
||||
11| " "
|
||||
12| " Render workspace context XML clearly. "
|
||||
13| <blank>
|
||||
14| "/workspace/project (tui-staging) deepseek-v"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-43 fg=bright-black
|
||||
15| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
8| "Additional instructions from: "
|
||||
style 0-43 dim
|
||||
9| "nested/AGENTS.md "
|
||||
style 0-15 dim
|
||||
10| " "
|
||||
11| "Render workspace context XML clearly. "
|
||||
style 0-36 dim
|
||||
12| <blank>
|
||||
13| "/workspace/project (tui-staging) deepseek-v"
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-43 dim
|
||||
14| " dsh > "
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
16-17| <blank>
|
||||
15-17| <blank>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
terminal 104x30 buffer=normal length=30 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=14 bufferRow=14
|
||||
cursor hidden column=7 viewportRow=13 bufferRow=13
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -16,22 +16,22 @@ buffer
|
||||
5| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
6| <blank>
|
||||
7| "Context · workspace-context "
|
||||
7| "Context · workspace-context"
|
||||
style 0-26 dim
|
||||
8| "system-reminder "
|
||||
style 0-14 fg=bright-black
|
||||
9| " Additional instructions from: nested/AGENTS.md "
|
||||
10| " "
|
||||
11| " Render workspace context XML clearly. "
|
||||
12| <blank>
|
||||
13| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
14| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
8| "Additional instructions from: nested/AGENTS.md "
|
||||
style 0-45 dim
|
||||
9| " "
|
||||
10| "Render workspace context XML clearly. "
|
||||
style 0-36 dim
|
||||
11| <blank>
|
||||
12| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
13| " dsh > "
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
15-29| <blank>
|
||||
14-29| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=20 bufferRow=20
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -15,33 +15,36 @@ buffer
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| <blank>
|
||||
6| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
7| "Old prompt with a long line that exercises wrapping before compaction. "
|
||||
8| <blank>
|
||||
9| "● Tool / bash / Run the coverage gate"
|
||||
style 0-36 fg=green
|
||||
10| "$ pnpm run test:coverage "
|
||||
style 0-23 fg=cyan
|
||||
style 0-23 dim
|
||||
11| "/workspace/project "
|
||||
style 0-17 dim
|
||||
12| "packages/ui/tui 100% "
|
||||
style 0-19 dim
|
||||
13| "… +1 lines (Ctrl+O to expand) "
|
||||
style 0-28 dim
|
||||
14| "1 test skipped "
|
||||
style 0-13 dim
|
||||
15| "coverage complete "
|
||||
style 0-16 dim
|
||||
16| "[exit 0] "
|
||||
style 0-7 dim
|
||||
17| "Model wait 0.0s "
|
||||
style 0-14 dim
|
||||
18| <blank>
|
||||
19| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
20| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
21-23| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "DSH snapshot"
|
||||
cursor hidden column=7 viewportRow=15 bufferRow=15
|
||||
viewport
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Snapshot agent ready."
|
||||
style 1-21 fg=bright-black
|
||||
style 1-21 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -18,21 +18,21 @@ viewport
|
||||
style 0-46 dim
|
||||
7| <blank>
|
||||
8| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
9| "Plan the work. "
|
||||
10| <blank>
|
||||
11| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
12| "Next question. "
|
||||
13| <blank>
|
||||
14| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
15| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
16-35| <blank>
|
||||
|
||||
@@ -4,10 +4,10 @@ title "Unsafe terminal title \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m"
|
||||
cursor hidden column=0 viewportRow=33 bufferRow=33
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 1-8 fg=bright-magenta bold
|
||||
style 10-16 bold
|
||||
1| " Unsafe welcome \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m"
|
||||
style 1-60 fg=bright-black
|
||||
style 1-60 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
@@ -15,51 +15,52 @@ buffer
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
5| <blank>
|
||||
6| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
style 0-2 fg=bright-magenta bold underline
|
||||
7| "Unsafe user \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
8| <blank>
|
||||
9| "● Tool / unsafe / Unsafe description \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m"
|
||||
style 0-81 fg=green
|
||||
10| "$ Unsafe title \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 0-59 fg=cyan
|
||||
style 0-59 dim
|
||||
11| "/unsafe/\\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 0-52 dim
|
||||
12| "Unsafe output \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 0-58 dim
|
||||
13| "[signal SIG\\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m] "
|
||||
style 0-56 fg=red
|
||||
14| "Model wait 0.0s · Completed 2026-07-21 15:00:00 "
|
||||
style 0-46 dim
|
||||
15| <blank>
|
||||
16| "Context · unsafe-\\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
16| "Context · unsafe-\\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m"
|
||||
style 0-61 dim
|
||||
17| "Unsafe context \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 0-59 fg=bright-black
|
||||
style 0-59 dim
|
||||
18| <blank>
|
||||
19| "Unsafe turn error \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 0-62 fg=red
|
||||
20-21| <blank>
|
||||
22| "Plan"
|
||||
style 0-3 fg=bright-blue bold
|
||||
style 0-3 fg=bright-magenta bold
|
||||
23| " ● Unsafe todo \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m"
|
||||
style 2-2 fg=yellow
|
||||
24| "/workspace/project (tui-staging) deepseek-v4-flash ↑0 ↓0 0% context"
|
||||
style 0-17 fg=bright-blue bold
|
||||
style 18-31 fg=bright-black
|
||||
style 34-50 fg=bright-black
|
||||
style 53-57 fg=bright-black
|
||||
style 60-69 fg=bright-black
|
||||
style 0-17 fg=bright-magenta bold
|
||||
style 18-31 dim
|
||||
style 34-50 dim
|
||||
style 53-57 dim
|
||||
style 60-69 dim
|
||||
25| " dsh > "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 1-3 fg=bright-magenta bold
|
||||
style 5-6 dim
|
||||
style 7-7 inverse
|
||||
26| " "
|
||||
27| " Question 1/1 (1 unanswered) · Unsafe header \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
style 2-90 fg=bright-black
|
||||
style 2-90 dim
|
||||
28| " Unsafe question \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m "
|
||||
29| " "
|
||||
30| " › 1. Unsafe option \\x1b]2;snapshot-controlled\\x07\\x09\\x7f\\x9b31m Unsafe detail \\x1b]2;snapshot-c "
|
||||
style 2-65 fg=bright-blue bold
|
||||
style 67-97 fg=bright-black
|
||||
style 2-65 fg=bright-magenta bold
|
||||
style 67-97 dim
|
||||
31| " Tab custom answer • Enter submit • Esc interrupt "
|
||||
style 2-49 dim
|
||||
32| " "
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Context } from 'cordis'
|
||||
import { agentEvents } from '@deepseek-ai/dsh-agent'
|
||||
import { createUserMessage, CallId, type ContentBlock , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm'
|
||||
import type {} from '@deepseek-ai/dsh-llm-retry'
|
||||
import { SessionId, type JsonValue, type Session } from '@deepseek-ai/dsh-session'
|
||||
import { SessionId, type JsonValue, type Session, type SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
import SessionReferenceService from '@deepseek-ai/dsh-session-reference'
|
||||
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
||||
import ToolRegistry, { type ToolDefinition, type ToolResultView } from '@deepseek-ai/dsh-tools'
|
||||
@@ -51,10 +51,12 @@ const CHECKPOINTS = [
|
||||
'surface-after-compaction-narrow',
|
||||
'surface-after-compaction-wide',
|
||||
'model-selector',
|
||||
'model-selector-filtered',
|
||||
'model-switching',
|
||||
'errors-and-help',
|
||||
'disposed-terminal',
|
||||
'resume-sessions',
|
||||
'resume-sessions-all-workspaces',
|
||||
'status-diagnostics',
|
||||
'status-diagnostics-narrow',
|
||||
'todo-plan-cleared',
|
||||
@@ -801,6 +803,10 @@ describe('TUI terminal-state snapshots', () => {
|
||||
harness.terminal.send('\r')
|
||||
})
|
||||
await checkpoint('model-selector', harness.terminal, { includeScrollback: true })
|
||||
await renderAfter(harness, () => {
|
||||
harness.terminal.send('pro')
|
||||
})
|
||||
await checkpoint('model-selector-filtered', harness.terminal, { includeScrollback: true })
|
||||
await renderAfter(harness, () => {
|
||||
harness.terminal.send('\x1b[B')
|
||||
harness.terminal.send('\r')
|
||||
@@ -812,35 +818,33 @@ describe('TUI terminal-state snapshots', () => {
|
||||
it('opens the searchable resume selector with log-backed session summaries', async () => {
|
||||
const dateNow = vi.spyOn(Date, 'now').mockReturnValue(Date.parse('2026-07-23T08:00:00.000Z'))
|
||||
const earlier = { version: 0, id: SessionId('earlier-session'), createdAt: Date.parse('2024-01-01T00:00:00Z'), cwd: '/workspace/project' }
|
||||
const elsewhere = { version: 0, id: SessionId('elsewhere-session'), createdAt: Date.parse('2024-02-02T00:00:00Z'), cwd: '/workspace/other' }
|
||||
const log = (meta: typeof earlier, title: string, day: string): { meta: typeof earlier; events: SessionEvent[] } => ({
|
||||
meta,
|
||||
events: [
|
||||
{ type: 'turn/start', seq: 0, time: Date.parse(`${day}T00:00:01Z`), data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } },
|
||||
{ type: 'user/message', seq: 1, time: Date.parse(`${day}T00:00:02Z`), data: createUserMessage({ content: [{ type: 'text', text: 'restore the selector' }], source: { kind: 'user' } }), surfaceOp: 'append' },
|
||||
{ type: 'step/start', seq: 2, time: Date.parse(`${day}T00:00:03Z`), data: { turn: 1, step: 1 } },
|
||||
{ type: 'request/header', seq: 3, time: Date.parse(`${day}T00:00:04Z`), data: { header: { config: { provider: 'deepseek', model: 'deepseek-v4-pro' } }, reason: 'initial' } },
|
||||
{ type: 'assistant/message', seq: 4, time: Date.parse(`${day}T00:00:05Z`), data: {
|
||||
turn: 1, step: 1,
|
||||
message: createMessage({
|
||||
role: 'assistant',
|
||||
content: [{ type: 'text', text: 'ready' }],
|
||||
source: { kind: 'model', provider: 'deepseek', model: 'deepseek-v4-pro' },
|
||||
}),
|
||||
}, surfaceOp: 'append' },
|
||||
{ type: 'step/end', seq: 5, time: Date.parse(`${day}T00:00:06Z`), data: { turn: 1, step: 1 } },
|
||||
{ type: 'turn/end', seq: 6, time: Date.parse(`${day}T00:00:07Z`), data: { turn: 1, reason: { kind: 'completed' } } },
|
||||
{ type: 'session/title', seq: 7, time: Date.parse(`${day}T00:00:08Z`), data: { title, messageSeqs: [1], source: { kind: 'fallback' } } },
|
||||
],
|
||||
})
|
||||
const harness = await setupSnapshot({
|
||||
config: { resumeCommand: 'dsh --resume {session}' },
|
||||
sessionPersistence: {
|
||||
list: async () => [earlier],
|
||||
load: async () => ({
|
||||
meta: earlier,
|
||||
events: [
|
||||
{ type: 'turn/start', seq: 0, time: Date.parse('2024-01-01T00:00:01Z'), data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } },
|
||||
{ type: 'user/message', seq: 1, time: Date.parse('2024-01-01T00:00:02Z'), data: createUserMessage({
|
||||
content: [{ type: 'text', text: 'restore the selector' }], source: { kind: 'user' },
|
||||
}), surfaceOp: 'append' },
|
||||
{ type: 'step/start', seq: 2, time: Date.parse('2024-01-01T00:00:03Z'), data: { turn: 1, step: 1 } },
|
||||
{ type: 'request/header', seq: 3, time: Date.parse('2024-01-01T00:00:04Z'), data: { header: { config: { provider: 'deepseek', model: 'deepseek-v4-pro' } }, reason: 'initial' } },
|
||||
{ type: 'assistant/message', seq: 4, time: Date.parse('2024-01-01T00:00:05Z'), data: {
|
||||
turn: 1, step: 1,
|
||||
message: createMessage({
|
||||
role: 'assistant',
|
||||
content: [{ type: 'text', text: 'ready' }],
|
||||
source: {
|
||||
kind: 'model',
|
||||
...{ provider: 'deepseek', model: 'deepseek-v4-pro' },
|
||||
},
|
||||
}),
|
||||
}, surfaceOp: 'append' },
|
||||
{ type: 'step/end', seq: 5, time: Date.parse('2024-01-01T00:00:06Z'), data: { turn: 1, step: 1 } },
|
||||
{ type: 'turn/end', seq: 6, time: Date.parse('2024-01-01T00:00:07Z'), data: { turn: 1, reason: { kind: 'completed' } } },
|
||||
{ type: 'session/title', seq: 7, time: Date.parse('2024-01-01T00:00:08Z'), data: { title: 'Resume selector design', messageSeqs: [1], source: { kind: 'fallback' } } },
|
||||
],
|
||||
}),
|
||||
list: async () => [earlier, elsewhere],
|
||||
load: async id => id === elsewhere.id
|
||||
? log(elsewhere, 'Other workspace work', '2024-02-02')
|
||||
: log(earlier, 'Resume selector design', '2024-01-01'),
|
||||
},
|
||||
}, { columns: 92, rows: 32 })
|
||||
harness.terminal.send('/resume')
|
||||
@@ -850,6 +854,12 @@ describe('TUI terminal-state snapshots', () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 60))
|
||||
await harness.terminal.flush()
|
||||
await checkpoint('resume-sessions', harness.terminal, { includeScrollback: true })
|
||||
// Tab switches to the all-workspaces scope, which adds the other workspace's
|
||||
// session and labels every row with the directory it belongs to.
|
||||
harness.terminal.send('\t')
|
||||
await new Promise(resolve => setTimeout(resolve, 60))
|
||||
await harness.terminal.flush()
|
||||
await checkpoint('resume-sessions-all-workspaces', harness.terminal, { includeScrollback: true })
|
||||
await disposeSnapshot(harness)
|
||||
dateNow.mockRestore()
|
||||
})
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
type TuiRuntime,
|
||||
} from '../src/index.ts'
|
||||
import { WorkspaceFileSearch } from '../src/chat/file-autocomplete.ts'
|
||||
import { ATTRIBUTE_ROLES, COLOR_ROLES, paletteSpec } from '../src/components/theme.ts'
|
||||
import {
|
||||
appendAssistant,
|
||||
appendUser,
|
||||
@@ -180,7 +181,7 @@ describe('TUI config', () => {
|
||||
color: true,
|
||||
truecolor: false,
|
||||
leftPrompt: '${cwd}${git/worktree}${model}${token_meter/cache_hit_rate}${context}',
|
||||
rightPrompt: '${timing}',
|
||||
rightPrompt: '${queued}',
|
||||
inputPrompt: '${symbol} ${indicator}',
|
||||
inputPlaceholder: 'press enter to steer and esc to cancel',
|
||||
},
|
||||
@@ -220,7 +221,7 @@ describe('TUI config', () => {
|
||||
color: false,
|
||||
truecolor: true,
|
||||
leftPrompt: '${cwd}${git/worktree}${model}${token_meter/cache_hit_rate}${context}',
|
||||
rightPrompt: '${timing}',
|
||||
rightPrompt: '${queued}',
|
||||
inputPrompt: '${symbol} ${indicator}',
|
||||
inputPlaceholder: 'press enter to steer and esc to cancel',
|
||||
},
|
||||
@@ -229,8 +230,7 @@ describe('TUI config', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('resume command and /resume', () => {
|
||||
const RESUME = 'dsh --resume {session}'
|
||||
describe('goodbye message and /resume', () => {
|
||||
const header = (id: string, createdAt: number, cwd: string): SessionHeader =>
|
||||
({ version: 0, id: SessionId(id), createdAt, cwd })
|
||||
const resumeEvents = (
|
||||
@@ -261,11 +261,10 @@ describe('resume command and /resume', () => {
|
||||
{ type: 'session/title', seq: 7, time: time + 7, data: { title, messageSeqs: [1], source: { kind: 'fallback' } } },
|
||||
]
|
||||
|
||||
it('prints the resume command on exit once the session is persisted', async () => {
|
||||
it('prints the host goodbye message on exit', async () => {
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
config: { resumeCommand: RESUME },
|
||||
sessionPersistence: { list: async () => [header('main-session', 1000, '/workspace')] },
|
||||
goodbyeMessage: 'To resume this session: dsh --resume main-session',
|
||||
})
|
||||
result.terminal.send('/exit')
|
||||
result.terminal.send('\r')
|
||||
@@ -275,8 +274,8 @@ describe('resume command and /resume', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('omits the exit hint when the session is not yet persisted', async () => {
|
||||
const result = await setup({ cwd: '/workspace', config: { resumeCommand: RESUME } })
|
||||
it('prints nothing on exit when the host supplies no goodbye message', async () => {
|
||||
const result = await setup({ cwd: '/workspace' })
|
||||
result.terminal.send('/exit')
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
@@ -285,17 +284,16 @@ describe('resume command and /resume', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('omits the exit hint when the session listing fails', async () => {
|
||||
it('escapes terminal controls in the host goodbye message', async () => {
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
config: { resumeCommand: RESUME },
|
||||
sessionPersistence: { list: () => Promise.reject(new Error('disk gone')) },
|
||||
goodbyeMessage: 'resume \u001b]2;hijacked\u0007now',
|
||||
})
|
||||
result.terminal.send('/exit')
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
expect(result.terminal.output).not.toContain('To resume this session')
|
||||
expect(result.exit).toHaveBeenCalledWith(0)
|
||||
expect(result.terminal.output).toContain('resume \\x1b]2;hijacked\\x07now')
|
||||
expect(result.terminal.output).not.toContain('\u001b]2;hijacked')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
@@ -305,7 +303,6 @@ describe('resume command and /resume', () => {
|
||||
const handoff = vi.fn<NonNullable<TuiRuntime['handoffResume']>>()
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
config: { resumeCommand: RESUME },
|
||||
handoffResume: handoff,
|
||||
sessionPersistence: {
|
||||
list: async () => [older, newer, header('foreign-session', 3000, '/elsewhere')],
|
||||
@@ -323,7 +320,10 @@ describe('resume command and /resume', () => {
|
||||
expect(output).toContain('Older investigation')
|
||||
expect(output).toContain('current · live')
|
||||
expect(output.indexOf('Newer product work')).toBeLessThan(output.indexOf('Older investigation'))
|
||||
// Default scope is the current workspace; one of the four records (three
|
||||
// listed plus the live current session) belongs to another.
|
||||
expect(output).not.toContain('foreign-session')
|
||||
expect(output).toContain('all workspaces (4)')
|
||||
result.terminal.send('Older')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('⌕ Older')
|
||||
@@ -351,7 +351,9 @@ describe('resume command and /resume', () => {
|
||||
await tick(); await tick()
|
||||
result.terminal.send('\x1b[B')
|
||||
result.terminal.send('\x1b[A')
|
||||
result.terminal.send('\t')
|
||||
// A key the search editor swallows without changing its value (backspace on
|
||||
// an empty box) keeps the selection and error untouched.
|
||||
result.terminal.send('\x7f')
|
||||
result.terminal.send('zz')
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
@@ -602,7 +604,6 @@ describe('resume command and /resume', () => {
|
||||
const corrupt = header('corrupt', 30, '/workspace')
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
config: { resumeCommand: RESUME },
|
||||
sessionPersistence: {
|
||||
list: async () => [missing, corrupt],
|
||||
load: async (id) => {
|
||||
@@ -683,7 +684,7 @@ describe('resume command and /resume', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('flushes, releases the terminal, and invokes one host handoff for the same SessionId', async () => {
|
||||
it('flushes, releases the terminal, and invokes one host handoff for the same SessionId and workspace', async () => {
|
||||
const target = header('target-session', 10, '/workspace')
|
||||
const handoff = vi.fn<NonNullable<TuiRuntime['handoffResume']>>(() => Promise.reject(new Error('test host retained process')))
|
||||
const result = await setup({
|
||||
@@ -701,7 +702,7 @@ describe('resume command and /resume', () => {
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
expect(handoff).toHaveBeenCalledTimes(1)
|
||||
expect(handoff).toHaveBeenCalledWith(target.id)
|
||||
expect(handoff).toHaveBeenCalledWith(target.id, '/workspace')
|
||||
expect(result.terminal.stopped).toBeGreaterThan(0)
|
||||
expect(result.terminal.output).toContain('Resume handoff failed: test host retained process')
|
||||
await dispose(result)
|
||||
@@ -817,7 +818,7 @@ describe('resume command and /resume', () => {
|
||||
result.terminal.send('Query without persistence')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
expect(handoff).toHaveBeenCalledWith(target.id)
|
||||
expect(handoff).toHaveBeenCalledWith(target.id, '/workspace')
|
||||
expect(result.terminal.output).toContain('Resume handoff failed: test host retained process')
|
||||
await dispose(result)
|
||||
})
|
||||
@@ -902,16 +903,23 @@ describe('resume command and /resume', () => {
|
||||
expect(result.terminal.output).not.toContain('host rejected after disposal')
|
||||
})
|
||||
|
||||
it('rejects a candidate whose cwd changes between listing and preflight', async () => {
|
||||
// A cwd that changes between listing and preflight is no longer a rejection:
|
||||
// resume targets whatever workspace the record names at preflight, so the
|
||||
// handoff must carry the RE-READ cwd rather than the one the row displayed.
|
||||
it('hands off with the cwd re-read at preflight, not the one listed', async () => {
|
||||
const target = header('moving-workspace', 10, '/workspace')
|
||||
const moved = header('moving-workspace', 10, '/elsewhere')
|
||||
const handoff = vi.fn<NonNullable<TuiRuntime['handoffResume']>>(
|
||||
() => Promise.reject(new Error('test host retained process')),
|
||||
)
|
||||
let listings = 0
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
handoffResume: vi.fn(),
|
||||
handoffResume: handoff,
|
||||
sessionPersistence: {
|
||||
list: async () => [++listings <= 2 ? target : header('moving-workspace', 10, '/elsewhere')],
|
||||
list: async () => [++listings <= 2 ? target : moved],
|
||||
load: async () => ({
|
||||
meta: listings <= 2 ? target : header('moving-workspace', 10, '/elsewhere'),
|
||||
meta: listings <= 2 ? target : moved,
|
||||
events: resumeEvents('Moving workspace'),
|
||||
}),
|
||||
},
|
||||
@@ -922,7 +930,101 @@ describe('resume command and /resume', () => {
|
||||
result.terminal.send('Moving workspace')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
expect(result.terminal.output).toContain('different workspace')
|
||||
expect(handoff).toHaveBeenCalledWith(target.id, '/elsewhere')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('keeps a session with no recorded workspace visible but disabled', async () => {
|
||||
// The key is omitted, not set to undefined: an explicit undefined is not
|
||||
// losslessly JSON-serializable and the header validator rejects it.
|
||||
const { cwd: _cwd, ...rootless } = header('no-workspace', 10, '/workspace')
|
||||
const handoff = vi.fn<NonNullable<TuiRuntime['handoffResume']>>()
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
handoffResume: handoff,
|
||||
sessionPersistence: {
|
||||
list: async () => [rootless],
|
||||
load: async () => ({ meta: rootless, events: resumeEvents('Rootless session') }),
|
||||
},
|
||||
})
|
||||
result.terminal.send('/resume')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
// A cwd-less session lists under all workspaces, never the current one.
|
||||
result.terminal.send('\t')
|
||||
await tick()
|
||||
result.terminal.send('Rootless session')
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('session has no recorded workspace')
|
||||
expect(handoff).not.toHaveBeenCalled()
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('lists other workspaces only in the all-workspaces scope and resumes into their cwd', async () => {
|
||||
const local = header('local-session', 2000, '/workspace')
|
||||
const foreign = header('foreign-session', 3000, '/elsewhere')
|
||||
const handoff = vi.fn<NonNullable<TuiRuntime['handoffResume']>>(
|
||||
() => Promise.reject(new Error('test host retained process')),
|
||||
)
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
handoffResume: handoff,
|
||||
sessionPersistence: {
|
||||
list: async () => [local, foreign],
|
||||
load: async id => id === local.id
|
||||
? { meta: local, events: resumeEvents('Local product work') }
|
||||
: { meta: foreign, events: resumeEvents('Foreign investigation') },
|
||||
},
|
||||
})
|
||||
result.terminal.send('/resume')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
// Three records: the two listed plus the live current session.
|
||||
expect(result.terminal.output).toContain('Local product work')
|
||||
expect(result.terminal.output).not.toContain('Foreign investigation')
|
||||
expect(result.terminal.output).toContain('all workspaces (3)')
|
||||
result.terminal.send('\t')
|
||||
await tick()
|
||||
const scoped = result.terminal.output.slice(result.terminal.output.lastIndexOf('Resume session'))
|
||||
expect(scoped).toContain('Foreign investigation')
|
||||
expect(scoped).toContain('workspace /elsewhere')
|
||||
expect(scoped).toContain('this workspace (2)')
|
||||
// Searching the workspace label reaches a row the title would not match.
|
||||
result.terminal.send('elsewhere')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
expect(handoff).toHaveBeenCalledWith(foreign.id, '/elsewhere')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('returns to the current workspace when Tab toggles back and clears the search', async () => {
|
||||
const local = header('scope-local', 2000, '/workspace')
|
||||
const foreign = header('scope-foreign', 3000, '/elsewhere')
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
handoffResume: vi.fn(),
|
||||
sessionPersistence: {
|
||||
list: async () => [local, foreign],
|
||||
load: async id => id === local.id
|
||||
? { meta: local, events: resumeEvents('Scope local') }
|
||||
: { meta: foreign, events: resumeEvents('Scope foreign') },
|
||||
},
|
||||
})
|
||||
result.terminal.send('/resume')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
result.terminal.send('\t')
|
||||
await tick()
|
||||
result.terminal.send('Scope foreign')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('⌕ Scope foreign')
|
||||
result.terminal.send('\t')
|
||||
await tick()
|
||||
const back = result.terminal.output.slice(result.terminal.output.lastIndexOf('Resume session'))
|
||||
expect(back).not.toContain('⌕ Scope foreign')
|
||||
expect(back).toContain('Scope local')
|
||||
expect(back).not.toContain('Scope foreign')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
@@ -1018,30 +1120,7 @@ describe('resume command and /resume', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('keeps resumeCommand as a displayed fallback when the host cannot hand off', async () => {
|
||||
const target = header('fallback-session', 10, '/workspace')
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
config: { resumeCommand: RESUME },
|
||||
sessionPersistence: {
|
||||
list: async () => [target],
|
||||
load: async () => ({ meta: target, events: resumeEvents('Fallback target') }),
|
||||
},
|
||||
})
|
||||
result.terminal.send('/resume')
|
||||
result.terminal.send('\r')
|
||||
await tick(); await tick()
|
||||
result.terminal.send('Fallback target')
|
||||
result.terminal.send('\r')
|
||||
await vi.waitFor(() => {
|
||||
expect(result.terminal.output).toContain('This host cannot hand off in place. Exit and run:')
|
||||
})
|
||||
expect(result.terminal.output).toContain('dsh --resume fallback-session')
|
||||
expect(result.terminal.stopped).toBe(0)
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('keeps the selector independent from an absent command fallback', async () => {
|
||||
it('warns without releasing the terminal when the host cannot hand off', async () => {
|
||||
const target = header('no-fallback-session', 10, '/workspace')
|
||||
const result = await setup({
|
||||
cwd: '/workspace',
|
||||
@@ -1058,6 +1137,7 @@ describe('resume command and /resume', () => {
|
||||
await vi.waitFor(() => {
|
||||
expect(result.terminal.output).toContain('Session is resumable, but this host cannot hand it off in place')
|
||||
})
|
||||
expect(result.terminal.stopped).toBe(0)
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
@@ -1330,10 +1410,16 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
expect(result.terminal.output).toContain('Steering')
|
||||
expect(result.terminal.output).toContain('user context')
|
||||
expect(result.terminal.output).toContain('Context · workspace-context')
|
||||
expect(result.terminal.output).toContain('system-reminder')
|
||||
// The redundant `system-reminder` frame element is dropped: the source label
|
||||
// already names the context, so the card body starts at the instruction text.
|
||||
expect(result.terminal.output).toContain('Additional instructions from: nested/AGENTS.md')
|
||||
expect(result.terminal.output).not.toContain('<system-reminder>')
|
||||
expect(result.terminal.output).toContain('\\x9b')
|
||||
expect(result.terminal.output).toContain('Render XML context clearly.')
|
||||
// A one-line frame has no open/close line pair to strip, so its text renders as
|
||||
// the prose it is. The card no longer parses context, so a character reference
|
||||
// stays literal instead of expanding to the control character it names — which
|
||||
// is why the expanded-C1 escaping the parser needed is no longer reachable here.
|
||||
expect(result.terminal.output).toContain('›')
|
||||
expect(result.terminal.output).not.toContain('\u009b')
|
||||
expect(result.terminal.output).toContain('Context · goal') // goal-sourced injected context labels by kind
|
||||
expect(result.terminal.output).toContain('Turn cancelled')
|
||||
expect(result.terminal.progress).toContain(true)
|
||||
@@ -1361,6 +1447,104 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
expect(result.terminal.drainInput).toHaveBeenCalledWith(100, 20)
|
||||
})
|
||||
|
||||
it('folds an injected-context card by default and expands it with Ctrl+O', async () => {
|
||||
const result = await setup()
|
||||
// A reminder body past the default 6-line budget so the collapsed card shows
|
||||
// the expand marker and hides a middle line until Ctrl+O.
|
||||
const instructions = Array.from({ length: 10 }, (_, index) => `instruction line ${index}`).join('\n')
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: `<system-reminder>\n${instructions}\n</system-reminder>` }],
|
||||
source: { kind: 'plugin', plugin: 'workspace-context' },
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
|
||||
// The redundant `system-reminder` frame element is dropped; the card is
|
||||
// collapsed by default with the shared Ctrl+O expand marker.
|
||||
expect(result.terminal.output).toContain('Context · workspace-context')
|
||||
expect(result.terminal.output).not.toContain('system-reminder')
|
||||
expect(result.terminal.output).toContain('lines (Ctrl+O to expand)')
|
||||
expect(result.terminal.output).toContain('instruction line 0')
|
||||
expect(result.terminal.output).not.toContain('instruction line 5')
|
||||
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Tool and context cards expanded.')
|
||||
expect(result.terminal.output).toContain('instruction line 5')
|
||||
|
||||
// Third state: tool cards hide; a context card is injected instructions,
|
||||
// not tool traffic, so it stays visible at its collapsed preview.
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Tool cards hidden.')
|
||||
// A repaint proves the context card SURVIVES the hidden phase: injected
|
||||
// instructions are not tool traffic, so they stay at the collapsed preview.
|
||||
result.terminal.send('\x0c')
|
||||
await tick()
|
||||
const hidden = result.terminal.output.slice(result.terminal.output.lastIndexOf('\x1b[2J'))
|
||||
expect(hidden).toContain('Context · workspace-context')
|
||||
// Fourth press returns to the collapsed default, closing the cycle.
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Tool and context cards collapsed.')
|
||||
|
||||
// Context with no frame renders as muted prose under the header; a frame
|
||||
// wrapping nothing renders header-only.
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'plain reminder text, no tags' }],
|
||||
source: { kind: 'plugin', plugin: 'plain-context' },
|
||||
}), { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: '<system-reminder>\n</system-reminder>' }],
|
||||
source: { kind: 'plugin', plugin: 'empty-context' },
|
||||
}), { surfaceOp: 'append' })
|
||||
// Only a matched open/close pair is a frame: an unpaired tag line is prose and
|
||||
// survives, so a body is never silently truncated by a tag-like first line.
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: '<available_skills>\nkept prose line\n</other-tag>' }],
|
||||
source: { kind: 'plugin', plugin: 'unpaired-context' },
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Context · plain-context')
|
||||
expect(result.terminal.output).toContain('plain reminder text, no tags')
|
||||
expect(result.terminal.output).toContain('Context · empty-context')
|
||||
expect(result.terminal.output).toContain('<available_skills>')
|
||||
expect(result.terminal.output).toContain('kept prose line')
|
||||
// Ctrl+L invalidates the mounted tree, exercising the card's invalidate hook.
|
||||
result.terminal.send('\x0c')
|
||||
await tick()
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('renders XML-hostile instruction prose verbatim, framed and folded', async () => {
|
||||
const result = await setup()
|
||||
// Real AGENTS.md prose carries a raw `&` (a badge URL's `&logo=`) and
|
||||
// angle-bracket placeholders that name nothing (`packages/<group>/<pkg>/`).
|
||||
// Both are prose the model must read literally, and neither may affect whether
|
||||
// the frame is stripped or the body folds.
|
||||
const lines = Array.from({ length: 10 }, (_, index) => `prose line ${index}`).join('\n')
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: `<system-reminder>\nbadge: https://img.shields.io/badge/x?style=flat&logo=deepseek\npath: packages/<group>/<pkg>/\n${lines}\n</system-reminder>`,
|
||||
}],
|
||||
source: { kind: 'plugin', plugin: 'prose-context' },
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
|
||||
expect(result.terminal.output).toContain('Context · prose-context')
|
||||
expect(result.terminal.output).not.toContain('<system-reminder>')
|
||||
expect(result.terminal.output).toContain('lines (Ctrl+O to expand)')
|
||||
expect(result.terminal.output).not.toContain('prose line 5')
|
||||
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('prose line 5')
|
||||
// Characters that break a strict XML parse survive unescaped and unexpanded.
|
||||
expect(result.terminal.output).toContain('&logo=deepseek')
|
||||
expect(result.terminal.output).toContain('packages/<group>/<pkg>/')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('counts failed and recovered request usage once per step', async () => {
|
||||
const result = await setup()
|
||||
result.session.append('assistant/chunk', {
|
||||
@@ -1445,10 +1629,10 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('badges queued steering on the prompt context timing and clears it as each drains', async () => {
|
||||
it('badges queued steering on the prompt context and clears it as each drains', async () => {
|
||||
// Pin a cwd free of the substring under test; the prompt context renders the path.
|
||||
const result = await setup({ status: 'running', cwd: '/workspace' })
|
||||
// Running with nothing queued: timing appears once in the prompt context and the editor keeps its hint.
|
||||
// Running with nothing queued: the badge is absent and the editor keeps its hint.
|
||||
expect(result.terminal.output).toContain('Assistant')
|
||||
expect(result.terminal.output).toContain('Model wait 0.0s')
|
||||
expect(result.terminal.output).toContain('press enter to steer and esc to cancel')
|
||||
@@ -1854,13 +2038,13 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
}
|
||||
|
||||
// Without truecolor there is no per-frame gray: below the fade midpoint the
|
||||
// glyph slot is blank; past it the glyph shows in the palette muted role
|
||||
// (ANSI 90), never the accent (SGR 94).
|
||||
// glyph slot is blank; past it the glyph shows in the palette dim role,
|
||||
// never the accent (ANSI 95).
|
||||
const early = await frameAt(60)
|
||||
expect(early).not.toMatch(/dsh(?:\x1b\[[0-9;]*m| )*●/u)
|
||||
const shown = await frameAt(300)
|
||||
expect(shown).toMatch(/\x1b\[90m●/u)
|
||||
expect(shown).not.toMatch(/\x1b\[94m●/u)
|
||||
expect(shown).toMatch(/\x1b\[2;39m●/u)
|
||||
expect(shown).not.toMatch(/\x1b\[95m●/u)
|
||||
|
||||
await dispose(result)
|
||||
})
|
||||
@@ -2065,8 +2249,7 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
})
|
||||
|
||||
expect(result.terminal.output).not.toContain('stale partial response')
|
||||
result.terminal.send('/reasoning')
|
||||
result.terminal.send('\r')
|
||||
result.terminal.send('\x12')
|
||||
result.terminal.send('\x1b[A')
|
||||
result.terminal.send('\x1b[A')
|
||||
result.terminal.send('\x1b[A')
|
||||
@@ -2231,8 +2414,7 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
expect(result.terminal.output).not.toContain('\u001B]2;unsafe\u0007')
|
||||
|
||||
result.terminal.resize(56)
|
||||
result.terminal.send('/redraw')
|
||||
result.terminal.send('\r')
|
||||
result.terminal.send('\x0c')
|
||||
await tick()
|
||||
|
||||
await dispose(result)
|
||||
@@ -2304,7 +2486,7 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
expect(result.agent.cancelled).toContainEqual({ kind: 'user' })
|
||||
|
||||
result.agent.status = 'idle'
|
||||
for (const command of ['/help', '/reasoning', '/tools', '/redraw', '/reload']) {
|
||||
for (const command of ['/help', '/palette', '/reload']) {
|
||||
result.terminal.send(command)
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
@@ -2321,7 +2503,7 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
|
||||
expect(result.terminal.output).toContain('Keyboard shortcuts')
|
||||
expect(result.terminal.output).toContain('Reasoning blocks')
|
||||
expect(result.terminal.output).toContain('Tool cards')
|
||||
expect(result.terminal.output).toContain('Tool and context cards')
|
||||
expect(result.terminal.output).toContain('Unknown command')
|
||||
// /reload without a Loader in the context degrades to a warning.
|
||||
expect(result.terminal.output).toContain('/reload needs the cordis Loader')
|
||||
@@ -3133,8 +3315,25 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
await vi.waitFor(() => {
|
||||
expect(result.terminal.output.slice(firstSelectorOutput)).toContain('Select model')
|
||||
})
|
||||
const filterOpenOutput = result.terminal.output.length
|
||||
result.terminal.send('beta')
|
||||
await tick()
|
||||
expect(result.terminal.output.slice(filterOpenOutput)).toContain('> beta')
|
||||
expect(result.terminal.output.slice(filterOpenOutput)).toContain('beta/b1')
|
||||
expect(result.terminal.output.slice(filterOpenOutput)).not.toContain('alpha/a1')
|
||||
const noMatchOutput = result.terminal.output.length
|
||||
result.terminal.send('zzz')
|
||||
await tick()
|
||||
expect(result.terminal.output.slice(noMatchOutput)).toContain('No models match the filter')
|
||||
result.terminal.send('\x1b[D')
|
||||
await tick()
|
||||
expect(result.terminal.output.slice(noMatchOutput)).toContain('No models match the filter')
|
||||
result.terminal.send('\x1b')
|
||||
await tick()
|
||||
const filterClearedOutput = result.terminal.output.length
|
||||
result.terminal.send('\x1b')
|
||||
await tick()
|
||||
expect(result.terminal.output.slice(filterClearedOutput)).not.toContain('Select model')
|
||||
|
||||
const providerDefaultOutput = result.terminal.output.length
|
||||
result.terminal.send('/model alpha/shared')
|
||||
@@ -3705,6 +3904,23 @@ describe('skill slash command', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('auto-invokes a launcher-seeded initial skill as the first turn', async () => {
|
||||
const result = await setup({ config: { initialSkill: 'demo-skill' }, configureContext: withSkills })
|
||||
// The seed rides the same path as a typed `/skill:demo-skill`, delivered
|
||||
// once the chat is live; no user input is required.
|
||||
await tick()
|
||||
expect(result.agent.sent).toEqual([[{ type: 'text', text: '<skill name="demo-skill">\nDemo instructions body.\n</skill>' }]])
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('reports an unknown initial skill as a notice without sending', async () => {
|
||||
const result = await setup({ config: { initialSkill: 'nope' }, configureContext: withSkills })
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Unknown skill: nope')
|
||||
expect(result.agent.sent).toEqual([])
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('reports an unknown skill and an empty skill name without sending', async () => {
|
||||
const result = await setup({ configureContext: withSkills })
|
||||
result.terminal.send('/skill:does-not-exist')
|
||||
@@ -3931,8 +4147,7 @@ describe('tool cards and surface replay', () => {
|
||||
}
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('$ raw command')
|
||||
result.terminal.send('/reasoning')
|
||||
result.terminal.send('\r')
|
||||
result.terminal.send('\x12')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('call presenter boom')
|
||||
expect(result.terminal.output).toContain('Symbol(input)')
|
||||
@@ -4066,8 +4281,7 @@ describe('tool cards and surface replay', () => {
|
||||
expect(output).toContain('line (number="1"): hello')
|
||||
expect(output).not.toContain('<result>')
|
||||
|
||||
result.terminal.send('/redraw')
|
||||
result.terminal.send('\r')
|
||||
result.terminal.send('\x0c')
|
||||
await tick()
|
||||
const collapsed = result.terminal.output.slice(result.terminal.output.lastIndexOf('\x1b[2J'))
|
||||
expect(collapsed).toContain('Run command')
|
||||
@@ -4077,7 +4291,7 @@ describe('tool cards and surface replay', () => {
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('world')
|
||||
expect(result.terminal.output).toContain('Tool cards expanded.')
|
||||
expect(result.terminal.output).toContain('Tool and context cards expanded.')
|
||||
expect(result.terminal.output).not.toContain('tools:expanded')
|
||||
expect(result.terminal.output).toContain('+ created')
|
||||
expect(result.terminal.output).toContain('console')
|
||||
@@ -4085,6 +4299,42 @@ describe('tool cards and surface replay', () => {
|
||||
// expanded (`+ after` is b.txt's new text; the footer counts both files).
|
||||
expect(result.terminal.output).toContain('+ after')
|
||||
expect(result.terminal.output).toContain('· 2 files')
|
||||
|
||||
// Third Ctrl+O phase hides every tool card: after a redraw the repainted
|
||||
// frame carries no tool header at all, only the conversation.
|
||||
result.terminal.send('\x0f')
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('Tool cards hidden.')
|
||||
// A result for an untracked call mints a fallback card mid-hidden: it must
|
||||
// adopt the current visibility instead of rendering collapsed.
|
||||
result.session.append('tool/result', {
|
||||
turn: 1, step: 1,
|
||||
message: createToolResultMessage({
|
||||
callId: 'untracked' as never,
|
||||
content: [{ type: 'text', text: 'fallback result body' }],
|
||||
isError: false,
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
await tick()
|
||||
result.terminal.send('\x0c')
|
||||
await tick()
|
||||
const hiddenFrame = result.terminal.output.slice(result.terminal.output.lastIndexOf('\x1b[2J'))
|
||||
expect(hiddenFrame).not.toContain('Tool / bash')
|
||||
expect(hiddenFrame).not.toContain('Run command')
|
||||
expect(hiddenFrame).not.toContain('fallback result body')
|
||||
// The dozen hidden cards leave no per-card blank rows behind: each card owns
|
||||
// its leading gap, so the trimmed frame has no long blank run where the
|
||||
// cards used to be.
|
||||
const frameRows = hiddenFrame.split('\n').map(row => row.replaceAll(/\x1b\[[0-9;]*[A-Za-z]/g, '').trim())
|
||||
const first = frameRows.findIndex(row => row.includes('Calling tools'))
|
||||
expect(first).toBeGreaterThan(-1)
|
||||
let blankRun = 0
|
||||
let longestRun = 0
|
||||
for (const row of frameRows.slice(first)) {
|
||||
blankRun = row === '' ? blankRun + 1 : 0
|
||||
longestRun = Math.max(longestRun, blankRun)
|
||||
}
|
||||
expect(longestRun).toBeLessThanOrEqual(2)
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
@@ -4111,6 +4361,46 @@ describe('tool cards and surface replay', () => {
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('drops blank rows from a terminal card result that the dim styling wraps', async () => {
|
||||
const blankRowTools: Record<string, ToolDefinition> = {
|
||||
trailing: {
|
||||
name: 'trailing', description: '', parameters: {}, output: UNUSED_TOOL_OUTPUT, execute: async () => [],
|
||||
presentCall: () => ({ card: 'terminal', title: 'printf out', description: 'Run it', cwd: '/tmp' }),
|
||||
// Real command output ends in a newline, so the split yields a trailing blank row.
|
||||
presentResult: () => ({ card: 'terminal', output: 'first\n\nlast\n', exitCode: 0 }),
|
||||
},
|
||||
}
|
||||
// Color on: the dim wrapper is what makes a blank row non-empty, so the
|
||||
// guard against wrapping one is only observable with ANSI enabled.
|
||||
const result = await setup({ tools: blankRowTools, config: { theme: { color: true } } })
|
||||
appendUser(result.session, 'run it')
|
||||
appendAssistant(result.session, [
|
||||
{ type: 'tool-call', id: 'blank' as never, name: 'trailing', arguments: '{}' },
|
||||
])
|
||||
result.session.append('tool/call', {
|
||||
turn: 1, step: 1, callId: 'blank' as never, name: 'trailing', arguments: '{}',
|
||||
})
|
||||
result.session.append('tool/result', {
|
||||
turn: 1, step: 1,
|
||||
message: createToolResultMessage({
|
||||
callId: 'blank' as never, content: [{ type: 'text', text: 'ignored' }], isError: false,
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
await tick()
|
||||
// Each output row is dim-wrapped, and the result's blank rows are dropped
|
||||
// rather than kept as dim-wrapped empty strings: `last` is the row right
|
||||
// after `first`, and no empty dim pair reaches the terminal.
|
||||
expect(result.terminal.output).toContain('\x1b[2;39mfirst\x1b[22;39m')
|
||||
expect(result.terminal.output).toContain('\x1b[2;39mlast\x1b[22;39m')
|
||||
expect(result.terminal.output).not.toContain('\x1b[2;39m\x1b[22;39m')
|
||||
const rows = result.terminal.output.split('\n')
|
||||
const firstRow = rows.findIndex(row => row.includes('first'))
|
||||
expect(firstRow).toBeGreaterThan(-1)
|
||||
expect(rows[firstRow + 1]).toContain('last')
|
||||
expect(rows[firstRow + 2]).toContain('[exit 0]')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('rebuilds after a surface replacement and hides shadowed tool calls', async () => {
|
||||
const result = await setup({ tools })
|
||||
appendUser(result.session, 'old prompt')
|
||||
@@ -4347,7 +4637,6 @@ describe('TUI extension service', () => {
|
||||
host.theme.accent(`${label} plugin overlay`),
|
||||
[
|
||||
host.theme.text('text'),
|
||||
host.theme.muted('muted'),
|
||||
host.theme.dim('dim'),
|
||||
host.theme.success('success'),
|
||||
host.theme.warning('warning'),
|
||||
@@ -4641,10 +4930,42 @@ describe('terminal mounting', () => {
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('detects a light terminal color scheme and switches from dark- to light-optimised ANSI codes', async () => {
|
||||
it('prints every palette role through /palette, each painted by the code it reports', async () => {
|
||||
const result = await setup({ config: { theme: { color: true } } })
|
||||
// Initial render uses dark-optimised palette: SGR 2 (dim) for dim text.
|
||||
expect(result.terminal.output).toContain('\x1b[90mdeepseek-v4-flash')
|
||||
const before = result.terminal.output.length
|
||||
result.terminal.send('/palette')
|
||||
result.terminal.send('\r')
|
||||
await tick()
|
||||
const printed = result.terminal.output.slice(before)
|
||||
|
||||
// Every declared role appears with its purpose, so a role added to the spec
|
||||
// without a listing entry (or the reverse) fails here rather than silently
|
||||
// going unlisted.
|
||||
const spec = paletteSpec('dark')
|
||||
for (const name of COLOR_ROLES) {
|
||||
expect(printed).toContain(name)
|
||||
expect(printed).toContain(spec.colors[name].purpose)
|
||||
}
|
||||
for (const name of ATTRIBUTE_ROLES) {
|
||||
expect(printed).toContain(name)
|
||||
expect(printed).toContain(spec.attributes[name].purpose)
|
||||
}
|
||||
|
||||
// Each row is painted by the role it names, so the listing cannot report one
|
||||
// code while rendering another: the sample carries the spec's own open code.
|
||||
expect(printed).toContain(`\x1b[${spec.colors.accent.open}m`)
|
||||
expect(printed).toContain(`\x1b[${spec.colors.dim.open}m`)
|
||||
expect(printed).toContain(`\x1b[${spec.attributes.selected.open}m`)
|
||||
// `text` is the terminal default, emitted as no escape at all.
|
||||
expect(printed).toContain('no escape')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
it('detects a light terminal color scheme and switches the scheme-dependent code role', async () => {
|
||||
const result = await setup({ config: { theme: { color: true } } })
|
||||
// `dim` is scheme-independent (SGR 2 over the default foreground), so the
|
||||
// startup render carries it on both schemes; `code` is the role that varies.
|
||||
expect(result.terminal.output).toContain('\x1b[2;39mdeepseek-v4-flash')
|
||||
|
||||
// A report matching the current scheme is a no-op: no palette rebuild or
|
||||
// re-render (ESC [?997;1n = dark, the startup default).
|
||||
@@ -4658,20 +4979,14 @@ describe('terminal mounting', () => {
|
||||
result.terminal.send('\x1b[?997;2n')
|
||||
await tick()
|
||||
await tick()
|
||||
// The rebuild re-renders under the light palette, where `code` is ANSI 34
|
||||
// (blue) rather than the dark scheme's ANSI 36 (cyan); `dim` is unchanged.
|
||||
expect(result.terminal.output).toContain('\x1b[2;39mdeepseek-v4-flash')
|
||||
|
||||
// After switching to light-optimised palette: palette.dim uses ANSI 90
|
||||
// (gray) instead of SGR 2. The header now uses \x1b[90m for the detail
|
||||
// line. The cumulative output still contains the initial SGR 2 render,
|
||||
// so we assert that a LATER write (appended after the scheme switch)
|
||||
// uses ANSI 90 for the same header text.
|
||||
expect(result.terminal.output).toContain('\x1b[90mdeepseek-v4-flash')
|
||||
|
||||
// Switch back to dark scheme.
|
||||
result.terminal.send('\x1b[?997;1n')
|
||||
await tick()
|
||||
await tick()
|
||||
// After switching back, a new write uses SGR 2 for the header detail.
|
||||
expect(result.terminal.output).toContain('\x1b[90mdeepseek-v4-flash')
|
||||
expect(result.terminal.output).toContain('\x1b[2;39mdeepseek-v4-flash')
|
||||
await dispose(result)
|
||||
})
|
||||
|
||||
@@ -4692,8 +5007,8 @@ describe('terminal mounting', () => {
|
||||
cwd: join(homedir(), 'projects', 'dsh-tui'),
|
||||
})
|
||||
await tick()
|
||||
expect(terminal.output).toContain('\x1b[94m~/')
|
||||
expect(terminal.output).toContain('\x1b[90m (tui-staging)')
|
||||
expect(terminal.output).toContain('\x1b[95m~/')
|
||||
expect(terminal.output).toContain('\x1b[2;39m (tui-staging)')
|
||||
await disposeTuiTestHarness(result)
|
||||
})
|
||||
it('runs /reload against every file-backed loader subtree, reports completion, and rejects re-entry while in flight', async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ const render = (source: string, limit = 4, expanded = false): string[] | undefin
|
||||
text => text.replace(/[\u0000-\u0009\u000b-\u001f\u007f-\u009f]/gu, control =>
|
||||
`\\x${control.charCodeAt(0).toString(16).padStart(2, '0')}`),
|
||||
text => `[label]${text}[/label]`,
|
||||
text => `[body]${text}[/body]`,
|
||||
count => ` … +${count} lines`,
|
||||
)
|
||||
|
||||
@@ -22,30 +23,38 @@ describe('unknown-tool XML rendering', () => {
|
||||
</content>
|
||||
</result>`)).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [label]path:[/label] /tmp/a.txt',
|
||||
' [label]type:[/label] file',
|
||||
' [label]path:[/label] [body]/tmp/a.txt[/body]',
|
||||
' [label]type:[/label] [body]file[/body]',
|
||||
' [label]content[/label]',
|
||||
' [label]line (number="1"):[/label] hello',
|
||||
' [label]line (number="2"):[/label] world',
|
||||
' [label]line (number="1"):[/label] [body]hello[/body]',
|
||||
' [label]line (number="2"):[/label] [body]world[/body]',
|
||||
])
|
||||
})
|
||||
|
||||
it('renders root text, CDATA, empty elements, and multiline nested text', () => {
|
||||
expect(render(' <result>\nfirst\nsecond\n</result> ')).toEqual([
|
||||
'[label]result[/label]',
|
||||
' first',
|
||||
' second',
|
||||
' [body]first[/body]',
|
||||
' [body]second[/body]',
|
||||
])
|
||||
expect(render('<result>\nfirst\nsecond\n</result>', 1, true)).toEqual([
|
||||
'[label]result[/label]',
|
||||
' first',
|
||||
' second',
|
||||
' [body]first[/body]',
|
||||
' [body]second[/body]',
|
||||
])
|
||||
expect(render('<result><value><![CDATA[literal <xml>]]></value><empty /></result>')).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [label]value:[/label] literal <xml>',
|
||||
' [label]value:[/label] [body]literal <xml>[/body]',
|
||||
' [label]empty[/label]',
|
||||
])
|
||||
// An interior blank line stays the empty string: styling it would emit an
|
||||
// escape-only row, which reads as a stray indented blank rather than a gap.
|
||||
expect(render('<result>\nfirst\n\nsecond\n</result>', 4, true)).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [body]first[/body]',
|
||||
'',
|
||||
' [body]second[/body]',
|
||||
])
|
||||
})
|
||||
|
||||
it('previews each top-level child independently and expands all rows', () => {
|
||||
@@ -53,13 +62,13 @@ describe('unknown-tool XML rendering', () => {
|
||||
expect(render(xml, 3)).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [label]first[/label]',
|
||||
' a',
|
||||
' [body]a[/body]',
|
||||
' … +4 lines',
|
||||
' f',
|
||||
' [body]f[/body]',
|
||||
' [label]second[/label]',
|
||||
' g',
|
||||
' [body]g[/body]',
|
||||
' … +4 lines',
|
||||
' l',
|
||||
' [body]l[/body]',
|
||||
])
|
||||
expect(render(xml, 3, true)).toHaveLength(15)
|
||||
})
|
||||
@@ -68,10 +77,10 @@ describe('unknown-tool XML rendering', () => {
|
||||
const xml = `<result>${Array.from({ length: 8 }, (_, index) => `<item>${index}</item>`).join('')}</result>`
|
||||
expect(render(xml, 3)).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [label]item:[/label] 0',
|
||||
' [label]item:[/label] 1',
|
||||
' [label]item:[/label] [body]0[/body]',
|
||||
' [label]item:[/label] [body]1[/body]',
|
||||
' … +5 lines',
|
||||
' [label]item:[/label] 7',
|
||||
' [label]item:[/label] [body]7[/body]',
|
||||
])
|
||||
expect(render(xml, 3, true)).toHaveLength(9)
|
||||
})
|
||||
@@ -79,11 +88,11 @@ describe('unknown-tool XML rendering', () => {
|
||||
it('escapes control characters expanded from character references', () => {
|
||||
expect(render('<result attr="a›b">tab	csi›</result>')).toEqual([
|
||||
'[label]result (attr="a\\\\x9bb")[/label]',
|
||||
' tab\\x09csi\\x9b',
|
||||
' [body]tab\\x09csi\\x9b[/body]',
|
||||
])
|
||||
expect(render('<result><value><![CDATA[del\u007f]]></value></result>')).toEqual([
|
||||
'[label]result[/label]',
|
||||
' [label]value:[/label] del\\x7f',
|
||||
' [label]value:[/label] [body]del\\x7f[/body]',
|
||||
])
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user