事件与输出
各运行时的输出各不相同,agentrun 把它们转成同一种带版本号的事件流,并统一判定成败。本页写事件的字段、subagent 与用量的规则、end.status 的判定,以及 jsonl、text、rich 三种输出格式。各运行时的原始输出怎么映射到这些事件,见运行。
代码位置
| 文件 | 主要类型与函数 | 本页对应的章节 |
|---|---|---|
src/output/event.rs | Event、Body、Start、SandboxKind、NetworkInfo、Prompt、ToolStart、Tool、Text、UsageReport、SubagentStart、SubagentStatus、SubagentEnd、Network、NetworkReason、End(early)、EndStatus、Signal | 统一事件流、end.status |
src/output/usage.rs | TokenCounts(context_tokens、total、summary)、Usage(sum)、tokens、cost | 用量与费用、text 格式里的用量与费用写法 |
src/output/aggregate.rs | Aggregator(begin、push、finish、main_calls、tokens)、Record、Translated | tool_start 与 tool 事件的时机、subagent 与 parent、用量合计、未结束调用的补发 |
src/output/mod.rs | Output(select、add_note)、write_end | text 格式、rich 格式 |
src/output/text.rs | TextFormatter(lines、add_note、subagent_label、subagent_model) | text 格式、[note] 行 |
src/output/rich.rs | Rich(add_note)、REFRESH_PERIOD、terminal_size | rich 格式 |
适配器输出的是 output::Record,Aggregator 把它们转成本页的事件:补 parent、给 subagent 编号、合计用量、在 end 之前补发未结束的调用与 subagent。其中 Record::CallStart(一次模型调用开始)与 Record::CallUsage(还没输出 usage 的调用到当时为止的用量)带 parent,不输出事件,运行框架每处理完一行原始输出,用 main_calls 与 tokens 检查轮数与 token 上限。三种输出格式都从同一个事件序列生成。理由:事件是唯一的事实来源,text 与 rich 只做展示。
统一事件流
--format jsonl 时,标准输出每行是一个 JSON 对象,每行写完立即 flush。第一个事件一定是 start,最后一个一定是 end;启动前就失败时只有一个 end。增加字段或增加事件类型时 schema 不变,调用方忽略不认识的 type;删除或改变已有字段的含义时加 1。每个事件的字段按下面类型定义里的顺序输出。
type Event =
| StartEvent | PromptEvent | ToolStartEvent | ToolEvent | TextEvent
| UsageEvent | SubagentStartEvent | SubagentEndEvent | NetworkEvent | EndEvent
interface EventBase {
schema: 1 // 事件格式的版本号
type: string
time: string // RFC 3339,UTC,精确到毫秒
}
// 运行时进程启动后输出一次
interface StartEvent extends EventBase {
type: "start"
runtime: "claude-code" | "codex" | "pi" | "dsh"
sandbox: "seatbelt" | "bubblewrap" | "codex" | "none"
network: {
mode: "none" | "full" | "custom"
allow: string[] // --allow-host 的值
enforced: boolean // 网络限制是否由沙箱执行
}
deny_read: string[] // agent 不能读的路径:默认列表在前,--deny-read 在后
model: string | null // --model 的值,未给时为 null
cwd: string // 真实的绝对路径,符号链接已展开
argv: string[] // 实际执行的完整命令,不含提示词
env: string[] // --env 与 --env-file 设置的变量名,不含值
}
// start 之后输出一次,内容是传给运行时的提示词
interface PromptEvent extends EventBase {
type: "prompt"
text: string
images: string[] // --image 给出的路径,按给出的顺序;没有图片时为 []
}
// 一次工具调用开始时输出
interface ToolStartEvent extends EventBase {
type: "tool_start"
id: string // 与这次调用的 tool 事件的 id 相同
parent: string | null // 与这次调用的 tool 事件的 parent 相同
name: string
summary: string // 与这次调用的 tool 事件的 summary 相同
}
// 一次工具调用结束时输出
interface ToolEvent extends EventBase {
type: "tool"
id: string // 运行时给出的工具调用 id
parent: string | null // 主 agent 为 null,subagent 内为 subagent_start.id
name: string // 运行时自己的工具名
summary: string // 一行,最长 120 个字符,超出时截断并加省略号
denied: boolean // 这次调用被运行时的权限机制拒绝
error: boolean | null // 这次调用执行出错;被拒绝时为 false,运行时没有报告时为 null
}
// agent 输出一段完整的文字时输出
interface TextEvent extends EventBase {
type: "text"
parent: string | null
text: string
}
// 一次模型调用结束时输出;运行时没报告的字段为 null
interface UsageEvent extends EventBase {
type: "usage"
parent: string | null
model: string | null
input_tokens: number | null // 不含缓存命中的部分
output_tokens: number | null
cache_read_tokens: number | null
cache_write_tokens: number | null
cost_usd: number | null // 这次调用的费用,单位美元
context_tokens: number | null // input_tokens、cache_read_tokens、cache_write_tokens 之和,即送进模型的全部上下文;三项有一项为 null 时为 null
}
// agent 启动一个 subagent 时输出
interface SubagentStartEvent extends EventBase {
type: "subagent_start"
id: string // 启动它的工具调用 id
parent: string | null
number: number // agentrun 按启动顺序给的编号,从 1 开始
kind: string // subagent 的类型,例如 "Explore"
model: string | null // 启动时给出的模型
description: string // 一行任务描述
}
// subagent 结束时输出
interface SubagentEndEvent extends EventBase {
type: "subagent_end"
id: string
status: "finished" | "failed"
duration_ms: number
usage: Usage // 这个 subagent 及其内部 subagent 的用量
}
// 经过过滤代理的连接,每组 host、port、allowed 第一次出现时输出
interface NetworkEvent extends EventBase {
type: "network"
host: string
port: number
allowed: boolean
reason: "not_allowed" | "private_address" | null // 放行时为 null
}
// 运行结束时输出
interface EndEvent extends EventBase {
type: "end"
status: "finished" | "failed" | "interrupted" | "timeout" | "limit" | "rejected"
exit_code: number | null // 运行时的退出码,未启动或被信号终止时为 null
detail: string
duration_ms: number // 从 agentrun 开始解析命令行到输出 end
usage: Usage
result: string | null // 主 agent 最后一段文字
session_id: string | null // 这次运行保存进 --session-dir 的会话 id,没有保存时为 null
}
interface TokenCounts {
input_tokens: number | null
output_tokens: number | null
cache_read_tokens: number | null
cache_write_tokens: number | null
cost_usd: number | null // 单位美元
}
interface Usage extends TokenCounts {
by_model: Record<string, TokenCounts> // 模型未知时键为 "unknown"
}
下面是一次运行的事件流,为了阅读把每行格式化成了多行,实际输出中每个事件占一行。
{
"schema": 1,
"type": "start",
"time": "2026-10-04T13:00:00.000Z",
"runtime": "claude-code",
"sandbox": "bubblewrap",
"network": {
"mode": "none",
"allow": [],
"enforced": true
},
"deny_read": [
"/home/me/.ssh",
"/home/me/.aws",
"..."
],
"model": null,
"cwd": "/work/repo",
"argv": [
"/usr/local/bin/claude",
"-p",
"--output-format",
"stream-json",
"..."
],
"env": [
"GH_TOKEN"
]
}
{
"schema": 1,
"type": "prompt",
"time": "2026-10-04T13:00:00.850Z",
"text": "给 parse 模块补测试并修复失败",
"images": []
}
{
"schema": 1,
"type": "subagent_start",
"time": "2026-10-04T13:00:03.120Z",
"id": "toolu_01",
"parent": null,
"number": 1,
"kind": "Explore",
"model": "haiku",
"description": "查找所有调用 parse_line 的位置"
}
{
"schema": 1,
"type": "tool_start",
"time": "2026-10-04T13:00:03.900Z",
"id": "toolu_02",
"parent": "toolu_01",
"name": "Grep",
"summary": "Grep: parse_line"
}
{
"schema": 1,
"type": "tool",
"time": "2026-10-04T13:00:04.410Z",
"id": "toolu_02",
"parent": "toolu_01",
"name": "Grep",
"summary": "Grep: parse_line",
"denied": false,
"error": false
}
{
"schema": 1,
"type": "usage",
"time": "2026-10-04T13:00:05.002Z",
"parent": "toolu_01",
"model": "claude-haiku-4-5",
"input_tokens": 3120,
"output_tokens": 85,
"cache_read_tokens": 9800,
"cache_write_tokens": 1200,
"cost_usd": null,
"context_tokens": 14120
}
{
"schema": 1,
"type": "subagent_end",
"time": "2026-10-04T13:00:15.530Z",
"id": "toolu_01",
"status": "finished",
"duration_ms": 12400,
"usage": {
"input_tokens": 3120,
"output_tokens": 85,
"cache_read_tokens": 9800,
"cache_write_tokens": 1200,
"cost_usd": null,
"by_model": {
"claude-haiku-4-5": {
"input_tokens": 3120,
"output_tokens": 85,
"cache_read_tokens": 9800,
"cache_write_tokens": 1200,
"cost_usd": null
}
}
}
}
{
"schema": 1,
"type": "tool_start",
"time": "2026-10-04T13:00:15.900Z",
"id": "toolu_03",
"parent": null,
"name": "Bash",
"summary": "Bash: cargo test"
}
{
"schema": 1,
"type": "tool",
"time": "2026-10-04T13:00:16.880Z",
"id": "toolu_03",
"parent": null,
"name": "Bash",
"summary": "Bash: cargo test",
"denied": false,
"error": false
}
{
"schema": 1,
"type": "text",
"time": "2026-10-04T13:00:31.100Z",
"parent": null,
"text": "测试全部通过。"
}
{
"schema": 1,
"type": "end",
"time": "2026-10-04T13:00:31.250Z",
"status": "finished",
"exit_code": 0,
"detail": "",
"duration_ms": 31250,
"usage": {
"input_tokens": 18234,
"output_tokens": 912,
"cache_read_tokens": 42000,
"cache_write_tokens": 5100,
"cost_usd": 0.0436916,
"by_model": {
"claude-sonnet-5-5": {
"input_tokens": 15114,
"output_tokens": 827,
"cache_read_tokens": 32200,
"cache_write_tokens": 3900,
"cost_usd": 0.0384916
},
"claude-haiku-4-5": {
"input_tokens": 3120,
"output_tokens": 85,
"cache_read_tokens": 9800,
"cache_write_tokens": 1200,
"cost_usd": 0.0052
}
}
},
"result": "测试全部通过。",
"session_id": null
}
提示词
prompt 让事件流本身记录这次运行的输入,读事件流的人不需要另外保存提示词。它取自运行时在输出里回显的提示词:claude-code 用 --replay-user-messages 回显,pi 的输出里本来就有用户消息。codex 与 dsh 不回显(codex 0.159.2 与 dsh 0.2.1-rc.2 实测),agentrun 在 start 之后用自己传入的提示词输出。运行时在回显之前就失败时,事件流里没有 prompt。images 列出调用方用 --image 给出的路径,不转成绝对路径,路径里不是 UTF-8 的字节换成 U+FFFD;不写图片内容,也不写 agentrun 在会话临时目录里写的副本路径,见图片。
运行时输出的非 JSON 行和未识别的事件不进入统一事件流,只写入 --raw 文件,不报错。运行时的标准错误原样转到 agentrun 的标准错误。
tool 事件在调用结束时输出
tool 在收到这次调用的结果时输出,因为调用是否被拒绝、是否出错要在调用之后才知道。运行时结束时还没有结果的调用,在 end 之前补发。被拒绝的调用不改变 end.status:运行时会把拒绝结果交还模型,由模型决定下一步,是否算失败由调用方根据 denied 判断。不提供「被拒绝即停止」的选项。
调用开始时先输出 tool_start,调用方据此显示正在执行的工具。同一次调用的 tool_start 与 tool 的 id、parent、name、summary 相同,parent 在调用开始时按已经启动的 subagent 确定,结束时沿用。每个 tool_start 之后都有一个同 id 的 tool,包括在 end 之前补发的。运行时只在调用结束时才报告这次调用的,tool_start 与 tool 一起输出。
denied 只表示运行时权限机制的拒绝,例如 claude-code 的 auto 模式分类器拒绝一条命令。被沙箱拦下的命令表现为命令出错,denied 为 false,error 为 true。pi 没有权限机制,dsh 在 agentrun 下关闭了它自己的审批(见dsh 一节),两者的 denied 恒为 false。
error 表示这次调用执行了但出错,例如命令的退出码不为 0、要读的文件不存在。取值来自运行时自己的报告,每个运行时用哪个字段见运行页各运行时的输出映射。被拒绝的调用没有执行,error 为 false。理由:claude-code 拒绝一次调用时,交还模型的结果也标为出错,只看 error 会把拒绝算成执行出错。运行时没有报告时 error 为 null,在 end 之前补发的 tool 也为 null。出错的调用同样不改变 end.status,理由与被拒绝的调用相同。
subagent 与 parent
主 agent 的事件 parent 为 null。subagent 内部的 tool_start、tool、text、usage、subagent_start 事件,parent 是启动它的 subagent_start 的 id;subagent 再启动 subagent 时按同样的规则嵌套。启动 subagent 的那次工具调用只输出 subagent_start 与 subagent_end,不输出 tool_start 与 tool。理由:调用方据此知道 subagent 何时开始与结束,不需要认识每个运行时的工具名。
主 agent 与多个 subagent 可以同时运行,它们的事件在流里交错出现。id 是运行时给出的工具调用 id,较长,用于关联事件;number 用于显示。
运行结束时还没结束的 subagent,在 end 之前补发 status 为 failed 的 subagent_end,duration_ms 记到运行结束时。subagent 失败不改变 end.status,理由是主 agent 可能已经处理了它的失败并完成任务。
subagent 与主 agent 在同一个运行时进程里运行,受同样的沙箱与权限限制。claude-code、codex 与 dsh 默认允许启动 subagent,给出 --no-subagents 时关闭;pi 没有 subagent。codex 的输出里没有 subagent 的启动事件与 subagent 内部的事件,所以 codex 的事件流里没有 subagent_start 与 subagent_end,subagent 做的事不出现在事件流里(codex 0.159.2 实测)。dsh 只输出主会话的事件,启动 subagent 的调用按普通工具调用输出 tool_start 与 tool,同样没有 subagent_start 与 subagent_end。
用量
用量属于一次模型调用,一次调用会产生多个 tool 与 text 事件,所以用量单独成一个 usage 事件,不附在其他事件上。
- claude-code 与 pi 每次模型调用都报告用量与模型,每次调用输出一个
usage事件。codex 每轮结束时报告一次,每轮一个usage事件。dsh 每一步(一次模型调用及其工具调用)结束时报告一次,每步一个usage事件。 input_tokens不含缓存命中的部分,四个运行时含义一致;context_tokens是input_tokens、cache_read_tokens、cache_write_tokens之和。- 运行时没报告的字段为 null。codex 与 dsh 的事件里没有模型名,
model为--model的值,没给时为 null。 - 运行时自己生成、没有调用模型的消息(claude-code 里 model 为
<synthetic>的错误文字)不输出usage。
end.usage 取运行时自己报告的整次运行总量;运行时没有总量时(pi、codex、dsh)取全部 usage 事件的合计。claude-code 的总量里有它内部的一笔 haiku 调用(auto 模式的分类器),这笔调用没有对应的 usage 事件,所以 end.usage 可能大于 usage 事件之和。理由:与实际计费一致。subagent_end.usage 是 parent 链上属于这个 subagent 的 usage 事件之和,只用于展示,已经包含在 end.usage 里。
end.usage 的字段为 input_tokens、output_tokens、cache_read_tokens、cache_write_tokens、cost_usd,另有 by_model 按模型给出同样的五个字段,模型未知时键为 unknown。合计只加非 null 的值,所有来源都没报告的字段为 null;一次运行没有任何用量时五个总量为 null,by_model 为 {}。
费用
cost_usd 是运行时自己报告的费用,单位美元,agentrun 不按单价计算。各运行时报告的范围不同:
| 运行时 | usage 事件 | end.usage | subagent_end.usage |
|---|---|---|---|
| claude-code | null,逐次调用的用量里没有费用 | 总量取最后一个 result 的 total_cost_usd,by_model 取 modelUsage 各模型的 costUSD。总量用运行时自己的合计,与 token 字段不同,不保证等于 by_model 之和;样本里两者相等 | null |
| pi | 这次调用的 usage.cost.total | usage 事件之和 | 没有 subagent |
| codex | null | null | 没有这个事件 |
| dsh | null | null | 没有这个事件 |
- claude-code 在输出第一个 result 之前结束时(例如第一轮还没完成就被中断或超时),
end.usage取usage事件的合计,cost_usd为 null。modelUsage为空时cost_usd也为 null,与 token 字段一致,即使total_cost_usd为 0。 - claude-code 与 pi 都按自己的单价表计算。claude-code 用订阅登录时同样给出按单价表计算的金额(
modelUsage的costBasis为list),与订阅的实际扣费无关。 - 合计是浮点数相加,jsonl 输出原始值,不做舍入。
end.status
按表中从上到下的顺序取第一个成立的状态。理由:超时、到达上限或被中断时,运行时可能已经输出了失败事件(例如 claude-code 收到 SIGINT 后的 result 为错误),这时调用方需要知道的是超时、上限或中断。
| status | 条件 | agentrun 退出码 |
|---|---|---|
rejected | 启动前失败,情形见启动前检查 | 2 |
interrupted | agentrun 收到 SIGINT 或 SIGTERM,以第一个信号为准 | 130 或 143 |
timeout | 超过 --timeout | 3 |
limit | 超过 --max-turns 或 --max-tokens(由 agentrun 自己计数),且运行时没有满足 finished 的条件,见轮数与 token 上限 | 4 |
failed | 运行时的失败条件成立,见运行。各运行时共有的条件:退出码非 0;正常退出却没有输出结果事件;运行中发现沙箱启动失败 | 1 |
finished | 以上都不成立 | 0 |
detail:failed时是运行时给出的错误信息,没有时是标准错误的最后 500 个字符,再没有时是一句固定说明;rejected时是原因与修正方法;limit时是哪个上限、上限值与实际值;timeout时是--timeout N reached,N 是给出的秒数;其余为空字符串。result:主 agent 最后一段文字,没有时为 null。调用方只需要答案时读这一项。interrupted、timeout与limit时,result与usage照常取已经收到的内容。session_id:给出--session-dir且运行时留下了会话记录时,是保存进去的会话 id,可以传给下一次运行的--resume;其余为 null。failed、interrupted、timeout与limit的运行只要留下了记录也照样保存,见保存与继续会话。
text 格式
--format text 每个事件以一行 [agent 标签] 事件类型 内容 开头,除 text 与 end 外都只占这一行。主 agent 的标签是 main,subagent 的标签是小写的类型加编号,例如 explore#1、general-purpose#2。没有 subagent 时也带 [main]。理由:主 agent 与 subagent 的事件交错出现,每行都带标签才能分辨来源,也能用 grep '^\[explore#1\]' 取出一个 subagent 的全部事件(text 的续行不带标签,取不到)。
tool:tool加summary。被拒绝时在summary后紧接(denied),执行出错时紧接(error)。tool_start:不显示,每次调用只在结束时由tool显示一行。prompt:prompt加提示词的第一行,标签是[main]。有图片时在后面加上(+1 image)或(+N images)。text:跳过空白行,第一行接在text后面,之后最多再显示 2 行,每行缩进 4 个空格;还有剩余时再加一行… (+N lines)(只剩 1 行时写(+1 line))。常量是text.rs的PREVIEW_LINES(3)。理由:模型的回答常以「Output:」这类引导句开头,只显示第一行看不到内容;全部显示又会让中途的每段说明占满屏幕。subagent_start:由启动它的 agent 的标签开头,写agent start 标签 (模型): 描述,模型未知时省去括号。subagent_end:由结束的 subagent 自己的标签开头,写agent 状态 耗时s 模型,后接用量。network:放行的连接不显示;被拒绝的显示一行[main] net denied 主机:端口 (原因)。代理不知道连接来自哪个 subagent,标签一律是[main]。usage:不单独显示,计入end行。end:[end] 状态 耗时s,后接用量、费用、session 会话id(session_id不为 null 时)与detail;费用写成$加四位小数,例如$0.0437,end.usage.cost_usd为 null 时省去;rejected时只写[end] rejected detail。end.result有非空白的内容,并且去掉空白行后多于 3 行,或者与主 agent 最后一段文字不同(逐行比较,忽略空白行与行尾空白)时,end行之前先输出一行[result],再原样输出result(只去掉开头与末尾的换行),理由:最终回答在text行里被截断时,调用方在终端里也要能读到完整答案;dsh 的result取自final,可能与最后一段文字不同,在达到上限而停止时也可能没有对应的文字。其余情况下text行已经完整显示了最终回答,不再重复。detail末尾的换行去掉,其余每个换行(\r\n、\n或\r)替换成一个空格,所以end也只占一行;jsonl 的detail字段保留原样。- 用量写成
in X out Y cached N%,各项之间、以及与前面的内容之间用两个空格。X 是input_tokens、cache_read_tokens与cache_write_tokens之和,缺失的项不计,三项都缺失时省去in;Y 是output_tokens,缺失时省去;N 是cache_read_tokens占 X 的百分比,四舍五入到整数,cache_read_tokens缺失或 X 为 0 时省去。理由:运行时报告的input_tokens只是没有命中缓存的部分,单独显示会让输入看起来接近零。 - token 数字:小于 100 写原值;小于 1,000,000 写成以千为单位、一位小数加
k(912 写成0.9k);更大的写成以百万为单位、一位小数加M。rich 格式的面板用同样的写法。jsonl 仍输出原始数字。 - 沙箱没有运行时,第一行是
[note]提示,见沙箱与网络。沙箱运行、--session-dir在工作目录之内时,第一行是[note] --session-dir DIR is inside the working directory. The agent can change the saved sessions,见保存与继续会话。[note]行在start事件的位置输出,jsonl 格式没有对应的事件。
一个 agent 显示的模型取它最近一次 usage 的 model;还没有 usage 时取 subagent_start 的 model,主 agent 取 start 的 model;都没有时不显示。
rich 格式
--format rich 在终端里显示动态界面,分三个区域。标准输出不是终端时,rich 按 text 输出。
- 滚动区。提示词、已完成的工具调用、文字与 subagent 的启动和结束按
text格式逐行输出,终端的滚动缓冲保留全部历史。最近 3 段文字(常量RECENT_TEXTS)按text格式显示多行,它们和其后的行先画在面板上方、每次随面板重画;出现第 4 段文字时,最早的一段只留第一行,和它后面直到下一段文字之前的行一起写入滚动区。这几段加上面板高于终端时,也按同样的方式从最早的一段开始折叠,理由:重画只能擦除屏幕上可见的行。运行结束时剩下的几段完整写入滚动区,再输出[result]与end行。制表符换成 4 个空格,理由:计算行数时要知道每行占几列。 - subagent 列表。出现过 subagent 之后才显示,每个运行中的 subagent 一行:动画、标签、模型、描述、它正在执行的工具、已运行时间、最近一次
usage的上下文占用。按启动顺序排列。subagent 结束后从列表移除,结束行进入滚动区。没有运行中的 subagent 时显示「0 running」。终端宽度不够时截断描述。标签与模型取自TextFormatter记下的值,与 text 格式显示的相同。 - 状态栏。动画、
main标签与主 agent 的模型、主 agent 正在执行的工具、已用时间、累计用量(到目前为止全部usage之和,包括 subagent,只写in与cached,不写out)、主 agent 的上下文占用。状态栏比终端宽度少用 3 列,宽度不够时先截断工具、再截断整行,理由:按 Ctrl-C 时终端在光标处回显^C,光标在状态栏末尾,状态栏占满一行时回显会折到下一行,结束时擦除少擦一行,面板的分隔线留在滚动区里。运行时没报告的项不显示。结束时状态栏换成end行,subagent 列表清除。
「正在执行的工具」从事件流取:rich 记下已经收到 tool_start、还没收到同 id 的 tool 的调用,按 parent 分到各个 agent,每个 agent 显示其中最近开始的一个。
面板每 100 毫秒重画一次,滚动区每输出一行也立即重画;动画每 100 毫秒换一帧。面板第一次出现时隐藏光标,结束时恢复。
rich 显示期间,如果标准错误也是终端,运行时写到标准错误的内容与 agentrun 自己写到标准错误的行(例如 [debug] 行)按行插入滚动区,不加标签与颜色,不完整的最后一行在运行结束时输出。理由:两路输出落在同一个终端上,直接写出会打在面板中间。标准错误不是终端时照常直接写出。
rich 只用暗色(SGR 2)显示滚动区的 agent 标签与面板的分隔线。环境变量 NO_COLOR 存在且不为空时不输出 SGR 序列,其他控制序列(移动光标、清屏、隐藏光标)照常输出。
已知限制:
- 运行中把终端变窄时,已经画出的面板行与面板上方最近几段文字会被终端折成多行,下一次擦除少擦几行,屏幕上留下残留。之后按新宽度绘制,不影响已经写入滚动区的内容。
- 面板不响应按键。运行中按键输入的字符会显示在面板上,被下一次重画覆盖。