Skip to content

Commit 3613050

Browse files
committed
new wsh command to save the scrollback
1 parent 597754a commit 3613050

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2025, Command Line Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package cmd
5+
6+
import (
7+
"fmt"
8+
"os"
9+
"strings"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/wavetermdev/waveterm/pkg/waveobj"
13+
"github.com/wavetermdev/waveterm/pkg/wshrpc"
14+
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
15+
)
16+
17+
var termScrollbackCmd = &cobra.Command{
18+
Use: "termscrollback",
19+
Short: "Get terminal scrollback from a terminal block",
20+
Long: `Get the terminal scrollback from a terminal block.
21+
22+
By default, retrieves all lines. You can specify line ranges or get the
23+
output of the last command using the --lastcommand flag.`,
24+
RunE: termScrollbackRun,
25+
PreRunE: preRunSetupRpcClient,
26+
DisableFlagsInUseLine: true,
27+
}
28+
29+
var (
30+
termScrollbackLineStart int
31+
termScrollbackLineEnd int
32+
termScrollbackLastCmd bool
33+
termScrollbackOutputFile string
34+
)
35+
36+
func init() {
37+
rootCmd.AddCommand(termScrollbackCmd)
38+
39+
termScrollbackCmd.Flags().IntVar(&termScrollbackLineStart, "start", 0, "starting line number (0 = beginning)")
40+
termScrollbackCmd.Flags().IntVar(&termScrollbackLineEnd, "end", 0, "ending line number (0 = all lines)")
41+
termScrollbackCmd.Flags().BoolVar(&termScrollbackLastCmd, "lastcommand", false, "get output of last command (requires shell integration)")
42+
termScrollbackCmd.Flags().StringVarP(&termScrollbackOutputFile, "output", "o", "", "write output to file instead of stdout")
43+
}
44+
45+
func termScrollbackRun(cmd *cobra.Command, args []string) (rtnErr error) {
46+
defer func() {
47+
sendActivity("termscrollback", rtnErr == nil)
48+
}()
49+
50+
// Resolve the block argument
51+
fullORef, err := resolveBlockArg()
52+
if err != nil {
53+
return err
54+
}
55+
56+
// Get block metadata to verify it's a terminal block
57+
metaData, err := wshclient.GetMetaCommand(RpcClient, wshrpc.CommandGetMetaData{
58+
ORef: *fullORef,
59+
}, &wshrpc.RpcOpts{Timeout: 2000})
60+
if err != nil {
61+
return fmt.Errorf("error getting block metadata: %w", err)
62+
}
63+
64+
// Check if the block is a terminal block
65+
viewType, ok := metaData[waveobj.MetaKey_View].(string)
66+
if !ok || viewType != "term" {
67+
return fmt.Errorf("block %s is not a terminal block (view type: %s)", fullORef.OID, viewType)
68+
}
69+
70+
// Make the RPC call to get scrollback
71+
scrollbackData := wshrpc.CommandTermGetScrollbackLinesData{
72+
LineStart: termScrollbackLineStart,
73+
LineEnd: termScrollbackLineEnd,
74+
LastCommand: termScrollbackLastCmd,
75+
}
76+
77+
result, err := wshclient.TermGetScrollbackLinesCommand(RpcClient, scrollbackData, &wshrpc.RpcOpts{
78+
Route: fullORef.String(),
79+
Timeout: 5000,
80+
})
81+
if err != nil {
82+
fmt.Fprintf(os.Stderr, "error getting terminal scrollback: %v\n", err)
83+
return err
84+
}
85+
86+
// Format the output
87+
output := strings.Join(result.Lines, "\n")
88+
if len(result.Lines) > 0 {
89+
output += "\n" // Add final newline
90+
}
91+
92+
// Write to file or stdout
93+
if termScrollbackOutputFile != "" {
94+
err = os.WriteFile(termScrollbackOutputFile, []byte(output), 0644)
95+
if err != nil {
96+
fmt.Fprintf(os.Stderr, "error writing to file %s: %v\n", termScrollbackOutputFile, err)
97+
return err
98+
}
99+
fmt.Printf("terminal scrollback written to %s (%d lines)\n", termScrollbackOutputFile, len(result.Lines))
100+
} else {
101+
fmt.Print(output)
102+
}
103+
104+
return nil
105+
}

docs/docs/wsh-reference.mdx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,57 @@ wsh setvar -b client MYVAR=value
792792
793793
Variables set with these commands persist across sessions and can be used to store configuration values, secrets, or any other string data that needs to be accessible across blocks or tabs.
794794
795+
---
796+
797+
## termscrollback
798+
799+
Get the terminal scrollback from a terminal block. This is useful for capturing terminal output for processing or archiving.
800+
801+
```sh
802+
wsh termscrollback [-b blockid] [flags]
803+
```
804+
805+
By default, retrieves all lines from the current terminal block. You can specify line ranges or get only the output of the last command.
806+
807+
Flags:
808+
809+
- `-b, --block <blockid>` - specify target terminal block (default: current block)
810+
- `--start <line>` - starting line number (0 = beginning, default: 0)
811+
- `--end <line>` - ending line number (0 = all lines, default: 0)
812+
- `--lastcommand` - get output of last command (requires shell integration)
813+
- `-o, --output <file>` - write output to file instead of stdout
814+
815+
Examples:
816+
817+
```sh
818+
# Get all scrollback from current terminal
819+
wsh termscrollback
820+
821+
# Get scrollback from a specific terminal block
822+
wsh termscrollback -b 2
823+
824+
# Get only the last command's output
825+
wsh termscrollback --lastcommand
826+
827+
# Get a specific line range (lines 100-200)
828+
wsh termscrollback --start 100 --end 200
829+
830+
# Save scrollback to a file
831+
wsh termscrollback -o terminal-log.txt
832+
833+
# Save last command output to a file
834+
wsh termscrollback --lastcommand -o last-output.txt
835+
836+
# Process last command output with grep
837+
wsh termscrollback --lastcommand | grep "ERROR"
838+
```
839+
840+
:::note
841+
The `--lastcommand` flag requires shell integration to be enabled. This feature allows you to capture just the output from the most recent command, which is particularly useful for scripting and automation.
842+
:::
843+
844+
---
845+
795846
## wavepath
796847
797848
The `wavepath` command lets you get the paths to various Wave Terminal directories and files, including configuration, data storage, and logs.

0 commit comments

Comments
 (0)