feat(cli): add paseo terminal command group for managing workspace terminals

New CLI commands: ls, create, kill, capture (tmux capture-pane style with
line range slicing and ANSI stripping), and send-keys (with special token
interpretation). Server-side adds capture_terminal_request RPC and
list-all-terminals support (optional CWD). Includes e2e tests and skill docs.
This commit is contained in:
Mohamed Boudra
2026-03-30 17:05:14 +07:00
parent 5b22aedaff
commit 0ba2f6b194
15 changed files with 938 additions and 9 deletions
+25 -2
View File
@@ -1116,7 +1116,7 @@ export const RegisterPushTokenMessageSchema = z.object({
export const ListTerminalsRequestSchema = z.object({
type: z.literal("list_terminals_request"),
cwd: z.string(),
cwd: z.string().optional(),
requestId: z.string(),
});
@@ -1172,6 +1172,15 @@ export const KillTerminalRequestSchema = z.object({
requestId: z.string(),
});
export const CaptureTerminalRequestSchema = z.object({
type: z.literal("capture_terminal_request"),
terminalId: z.string(),
start: z.number().int().optional(),
end: z.number().int().optional(),
stripAnsi: z.boolean().default(true),
requestId: z.string(),
});
export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
VoiceAudioChunkMessageSchema,
AbortRequestMessageSchema,
@@ -1235,6 +1244,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
UnsubscribeTerminalRequestSchema,
TerminalInputSchema,
KillTerminalRequestSchema,
CaptureTerminalRequestSchema,
ChatCreateRequestSchema,
ChatListRequestSchema,
ChatInspectRequestSchema,
@@ -2158,7 +2168,7 @@ export const TerminalStateSchema = z
export const ListTerminalsResponseSchema = z.object({
type: z.literal("list_terminals_response"),
payload: z.object({
cwd: z.string(),
cwd: z.string().optional(),
terminals: z.array(TerminalInfoSchema.omit({ cwd: true })),
requestId: z.string(),
}),
@@ -2207,6 +2217,16 @@ export const KillTerminalResponseSchema = z.object({
}),
});
export const CaptureTerminalResponseSchema = z.object({
type: z.literal("capture_terminal_response"),
payload: z.object({
terminalId: z.string(),
lines: z.array(z.string()),
totalLines: z.number().int().nonnegative(),
requestId: z.string(),
}),
});
export const TerminalStreamExitSchema = z.object({
type: z.literal("terminal_stream_exit"),
payload: z.object({
@@ -2276,6 +2296,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
CreateTerminalResponseSchema,
SubscribeTerminalResponseSchema,
KillTerminalResponseSchema,
CaptureTerminalResponseSchema,
TerminalStreamExitSchema,
ChatCreateResponseSchema,
ChatListResponseSchema,
@@ -2468,6 +2489,8 @@ export type TerminalCursor = z.infer<typeof TerminalCursorSchema>;
export type TerminalState = z.infer<typeof TerminalStateSchema>;
export type KillTerminalRequest = z.infer<typeof KillTerminalRequestSchema>;
export type KillTerminalResponse = z.infer<typeof KillTerminalResponseSchema>;
export type CaptureTerminalRequest = z.infer<typeof CaptureTerminalRequestSchema>;
export type CaptureTerminalResponse = z.infer<typeof CaptureTerminalResponseSchema>;
export type TerminalStreamExit = z.infer<typeof TerminalStreamExitSchema>;
// ============================================================================